commit 4e43fe1aba3f3039fb6895c6e3b288261bd70f35 Author: Nalvazhuthi Date: Fri Mar 14 12:57:01 2025 +0530 first commit diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..a1ab2df --- /dev/null +++ b/.dockerignore @@ -0,0 +1,34 @@ +# Include any files or directories that you don't want to be copied to your +# container here (e.g., local build artifacts, temporary files, etc.). +# +# For more help, visit the .dockerignore file reference guide at +# https://docs.docker.com/go/build-context-dockerignore/ + +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/.next +**/.cache +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/charts +**/docker-compose* +**/compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +**/build +**/dist +LICENSE +README.md \ No newline at end of file diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..b39b401 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,23 @@ +services: + frontend: + build: + context: ./frontend + args: + - REACT_APP_SERVER_SOCKET_API_BASE_URL=185.100.212.76:8000 + - REACT_APP_SERVER_REST_API_BASE_URL=185.100.212.76:5000 + - REACT_APP_SERVER_MARKETPLACE_URL=185.100.212.76:50011 + container_name: dwinzo-frontend + stdin_open: true + tty: true + ports: + - "3003:3000" + environment: + - WDS_SOCKET_PORT=0 + - PORT=3000 + - DOCSIFY_PORT=8201 + volumes: + - ./frontend:/app + +volumes: + frontend: + driver: local diff --git a/frontend/.dockerignore b/frontend/.dockerignore new file mode 100644 index 0000000..a1ab2df --- /dev/null +++ b/frontend/.dockerignore @@ -0,0 +1,34 @@ +# Include any files or directories that you don't want to be copied to your +# container here (e.g., local build artifacts, temporary files, etc.). +# +# For more help, visit the .dockerignore file reference guide at +# https://docs.docker.com/go/build-context-dockerignore/ + +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/.next +**/.cache +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/charts +**/docker-compose* +**/compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +**/build +**/dist +LICENSE +README.md \ No newline at end of file diff --git a/frontend/.env b/frontend/.env new file mode 100644 index 0000000..bff5be3 --- /dev/null +++ b/frontend/.env @@ -0,0 +1,14 @@ +# PORT for the main application (frontend). +PORT=8200 + +# Port on which the Docsify documentation server will run. +DOCSIFY_PORT=8201 + +# Base URL for the server socket API, used for real-time communication (e.g., WebSockets). +REACT_APP_SERVER_SOCKET_API_BASE_URL=185.100.212.76:8000 + +# Base URL for the server REST API, used for HTTP requests to the backend server. +REACT_APP_SERVER_REST_API_BASE_URL=185.100.212.76:5000 + +# Base URL for the server marketplace API. +REACT_APP_SERVER_MARKETPLACE_URL=185.100.212.76:50011 \ No newline at end of file diff --git a/frontend/.github/ISSUE_TEMPLATE/bug_report.md b/frontend/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..1f1d7b5 --- /dev/null +++ b/frontend/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,40 @@ +--- +name: Bug Report +about: Report a bug or issue with the project +title: "[Bug] " +labels: bug +assignees: '' + +--- + +### Bug Description + +Provide a detailed description of the bug or issue. + + +### Steps to Reproduce + +1. Step one +2. Step two +3. Step three + +### Expected Behavior + +Explain what you expected to happen. + + +### Actual Behavior + +Describe what actually happened, including any error messages or logs. + + +### Screenshots (if applicable) + +If applicable, add screenshots to help explain your problem. + + +### Environment Information: + +- Operating System: [e.g., macOS, Windows, Linux] +- Browser (if applicable): [e.g., Chrome, Firefox] +- Version: [e.g., 1.0.0] diff --git a/frontend/.github/ISSUE_TEMPLATE/feature_request.md b/frontend/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..6715d4c --- /dev/null +++ b/frontend/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,22 @@ +--- +name: Feature Request +about: Suggest a new feature for the project +title: "[Feature Request] " +labels: enhancement +assignees: '' + +--- + +### Feature Request Description + +Provide a clear and concise description of the feature you’d like to request. + + +### Why Is This Feature Needed? + +Explain why the feature would be useful or necessary. + + +### Additional Context + +Add any other context or screenshots that may help describe the feature request. diff --git a/frontend/.github/PULL_REQUEST_TEMPLATE/bug_fix.md b/frontend/.github/PULL_REQUEST_TEMPLATE/bug_fix.md new file mode 100644 index 0000000..17e679b --- /dev/null +++ b/frontend/.github/PULL_REQUEST_TEMPLATE/bug_fix.md @@ -0,0 +1,24 @@ +### Description + +Please include a summary of the changes and the motivation behind them. Also include any relevant context or links to related issues. + +**Related Issues:** + +- Issue # (if applicable) +- Link to related issue or ticket (if applicable) + +### Changes Made + +- Describe what changes were made in this pull request. +- Include any relevant details about the implementation. + +### Checklist + +- [ ] I have tested my changes locally. +- [ ] I have updated the documentation (if applicable). +- [ ] I have included unit tests (if applicable). +- [ ] My code follows the project's coding style. + +### Screenshots (if applicable) + +![screenshot](link_to_screenshot) diff --git a/frontend/.github/PULL_REQUEST_TEMPLATE/documentation.md b/frontend/.github/PULL_REQUEST_TEMPLATE/documentation.md new file mode 100644 index 0000000..0d5b3ff --- /dev/null +++ b/frontend/.github/PULL_REQUEST_TEMPLATE/documentation.md @@ -0,0 +1,24 @@ +--- +name: Documentation Update +about: Submit a pull request for updating documentation +title: "[Docs] " +labels: documentation, needs review +assignees: '' + +--- + +### Documentation Changes + +Please describe the changes you are making to the documentation. + +### Related Code Changes (if applicable) + +If your documentation relates to any new code changes, please provide context or links to those changes. + +### Reason for Change + +Why are these documentation updates necessary? + +### Screenshots (if applicable) + +If updating visual elements of documentation, provide screenshots or examples. diff --git a/frontend/.github/PULL_REQUEST_TEMPLATE/feature_request.md b/frontend/.github/PULL_REQUEST_TEMPLATE/feature_request.md new file mode 100644 index 0000000..3c0dc1c --- /dev/null +++ b/frontend/.github/PULL_REQUEST_TEMPLATE/feature_request.md @@ -0,0 +1,28 @@ +--- +name: Feature Request +about: Submit a pull request for adding a new feature +title: "[Feature] " +labels: enhancement, needs review +assignees: '' + +--- + +### Description of the Feature + +Briefly describe the new feature you are implementing. + +**Related Issue:** (if any) + +### Changes Made + +1. context-menu-list the specific changes made in the code. +2. Explain the new functionality and how it improves the project. + +### Testing and Documentation + +1. Steps for testing the new feature. +2. Any documentation updates made. + +### Screenshots (if applicable) + +Add any screenshots or visuals demonstrating the feature. diff --git a/frontend/.github/workflows/ci.yml b/frontend/.github/workflows/ci.yml new file mode 100644 index 0000000..e69de29 diff --git a/frontend/.github/workflows/deploy-docs.yml b/frontend/.github/workflows/deploy-docs.yml new file mode 100644 index 0000000..d509cba --- /dev/null +++ b/frontend/.github/workflows/deploy-docs.yml @@ -0,0 +1,24 @@ +name: Deploy Docsify + +on: + push: + branches: + - main + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Install Node.js + uses: actions/setup-node@v3 + with: + node-version: 16 + + - name: Install dependencies + run: npm install + + - name: Build Docsify site + run: docsify serve docs --port 4000 diff --git a/frontend/.gitignore b/frontend/.gitignore new file mode 100644 index 0000000..b2614db --- /dev/null +++ b/frontend/.gitignore @@ -0,0 +1,28 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* + + +# remove zip +*.zip +**/temp/ diff --git a/frontend/.husky/documents/readme.md b/frontend/.husky/documents/readme.md new file mode 100644 index 0000000..e69de29 diff --git a/frontend/.husky/pre-commit b/frontend/.husky/pre-commit new file mode 100644 index 0000000..d461e99 --- /dev/null +++ b/frontend/.husky/pre-commit @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +echo "Running pre-commit hook..." + +# Compile TypeScript +echo "Compiling TypeScript..." +npx tsc scripts/validate-filenames.ts + +# if [ $? -ne 0 ]; then +# echo "TypeScript compilation failed. Aborting commit." +# exit 1 +# fi + +echo "TypeScript compilation successful." + +# Run Node.js script +echo "Running Node.js script..." +node scripts/validate-filenames.js --no-prompt + +if [ $? -ne 0 ]; then + echo "Node.js script failed. Aborting commit." + exit 1 +fi + +echo "Pre-commit hook completed successfully." diff --git a/frontend/.husky/pre-push b/frontend/.husky/pre-push new file mode 100644 index 0000000..e69de29 diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..b85937d --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,51 @@ +# Use the argument for node version (defaults to 'lts' if not provided) +ARG NODE_VERSION=lts + +# Stage 1: Build React App +FROM node:${NODE_VERSION}-alpine AS development + +# Set the Node.js environment to development +ENV NODE_ENV=development + +# Define build arguments for the API base URLs +ARG REACT_APP_SERVER_SOCKET_API_BASE_URL +ARG REACT_APP_SERVER_REST_API_BASE_URL +ARG REACT_APP_SERVER_MARKETPLACE_URL + +# Set environment variables for the API base URLs using the build arguments +ENV REACT_APP_SERVER_SOCKET_API_BASE_URL=${REACT_APP_SERVER_SOCKET_API_BASE_URL} +ENV REACT_APP_SERVER_REST_API_BASE_URL=${REACT_APP_SERVER_REST_API_BASE_URL} +ENV REACT_APP_SERVER_MARKETPLACE_URL=${REACT_APP_SERVER_MARKETPLACE_URL} + +# Set working directory for frontend code +WORKDIR /frontend + +# Copy package.json and package-lock.json for npm install +COPY package*.json ./ + +# Install the latest npm version +RUN npm install -g npm + +# Install dependencies (this includes react-scripts) +RUN npm install --legacy-peer-deps + +# Copy the rest of the application code +COPY . . + +# Run the build command (build the React app) +RUN npm run build + +# Stage 2: Serve with Nginx +FROM nginx:alpine + +# Copy the built React files from the build stage into Nginx's default HTML folder +COPY --from=development /frontend/build /usr/share/nginx/html + +# Optionally copy a custom Nginx config (if needed) +COPY nginx.conf /etc/nginx/conf.d/default.conf + +# Expose port 80 for Nginx (default HTTP port) +EXPOSE 80 + +# Start Nginx in the foreground (this is required to keep the container running) +CMD ["nginx", "-g", "daemon off;"] diff --git a/frontend/README.md b/frontend/README.md new file mode 100644 index 0000000..92aa449 --- /dev/null +++ b/frontend/README.md @@ -0,0 +1,99 @@ +## Getting Started + +Follow these steps to set up and run the project locally. + +### Prerequisites + +Ensure you have the following installed on your system: + +- **Node.js**: [Download and install Node.js](https://nodejs.org/) +- **npm**: Comes with Node.js, but you can also install [npm separately](https://www.npmjs.com/get-npm) +- **yarn (optional)**: If you prefer to use Yarn, [install it here](https://yarnpkg.com/) +- **TypeScript**: This project uses TypeScript, and the necessary dependencies will be installed automatically. + +### Installation + +1. Clone the repository: + + ```bash + git clone http://185.100.212.76:7776/Vishnu/Dwinzo.git + cd Dwinzo + ``` + + - Cloning repository with User Credentials: + + ```bash + git clone http://your_username:password@185.100.212.76:7776/Vishnu/Dwinzo.git + cd Dwinzo + ``` + + note: if password contains special charecters use: + + - @ → %40 + - : → %3A + - / → %2F + - ? → %3F + - & → %26 + - = → %3D + - ! → %21 + +2. Install the dependencies: + + ```bash + npm install + ``` + +3. Start server: + + ```bash + npm start + ``` + +4. Build the app for production: + + ```bash + npm run build + ``` + +5. Tests + + This project includes both **unit tests** using **Jest** and **end-to-end (E2E) tests** using **Cypress**. Here’s how you can run and manage these tests. + + **Unit Tests (Jest)** + Unit tests are located in the `src/tests/unit/` directory. They test individual components and functions to ensure they work as expected. **Jest** is used for running these tests. + + **Running Unit Tests** + To run the unit tests, use the following command: + + ```bash + npm run test + ``` + + **End-to-End (E2E) Tests (Cypress)** + Cypress can be run in two modes + + 1. Interactive Mode: + + ```bash + npm run cypress:open + ``` + + 2. Headless Mode: + + ```bash + npm run cypress:run + ``` + +### Run Docsify + +1. Installation (if needed): + + ```bash + npm i docsify-cli -g + ``` + +2. Run Command: + + ```bash + docsify serve docs + ``` diff --git a/frontend/docs/.gitignore b/frontend/docs/.gitignore new file mode 100644 index 0000000..af253e0 --- /dev/null +++ b/frontend/docs/.gitignore @@ -0,0 +1 @@ +/.obsidian \ No newline at end of file diff --git a/frontend/docs/.nojekyll b/frontend/docs/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/frontend/docs/README.md b/frontend/docs/README.md new file mode 100644 index 0000000..ae36ae4 --- /dev/null +++ b/frontend/docs/README.md @@ -0,0 +1,93 @@ +# Getting Started + +Follow these steps to set up and run the project locally. + +## Prerequisites + +Ensure you have the following installed on your system: + +- **Node.js**: [Download and install Node.js](https://nodejs.org/) +- **npm**: Comes with Node.js, but you can also install [npm separately](https://www.npmjs.com/get-npm) +- **yarn (optional)**: If you prefer to use Yarn, [install it here](https://yarnpkg.com/) +- **TypeScript**: This project uses TypeScript, and the necessary dependencies will be installed automatically. +--- +## Installation + +1. Clone the repository: + + ```bash + git clone http://185.100.212.76:7776/Vishnu/Dwinzo.git + cd Dwinzo + ``` + + - Cloning repository with User Credentials: + + ```bash + git clone http://your_username:password@185.100.212.76:7776/Vishnu/Dwinzo.git + cd Dwinzo + ``` + + note: if password contains special charecters use: + + - @ → %40 + - : → %3A + - / → %2F + - ? → %3F + - & → %26 + - = → %3D + - ! → %21 + +2. Install the dependencies: + + ```bash + npm install + ``` + +3. Start server: + + ```bash + npm start + ``` + +4. Build the app for production: + + ```bash + npm run build + ``` + +5. Tests + + This project includes both **unit tests** using **Jest** and **end-to-end (E2E) tests** using **Cypress**. Here’s how you can run and manage these tests. + + **Unit Tests (Jest)** + Unit tests are located in the `src/tests/unit/` directory. They test individual components and functions to ensure they work as expected. **Jest** is used for running these tests. + + **Running Unit Tests** + To run the unit tests, use the following command: + + ```bash + npm run test + ``` + + **End-to-End (E2E) Tests (Cypress)** + Cypress can be run in two modes + + 1. Interactive Mode: + + ```bash + npm run cypress:open + ``` + + 2. Headless Mode: + + ```bash + npm run cypress:run + ``` +--- +## Documentation + +Run the local server with `docsify serve`. You can preview your site in your browser on `http://localhost:3000`. + +```bash +docsify serve docs +``` diff --git a/frontend/docs/_navbar.md b/frontend/docs/_navbar.md new file mode 100644 index 0000000..e69de29 diff --git a/frontend/docs/_sidebar.md b/frontend/docs/_sidebar.md new file mode 100644 index 0000000..54a0d40 --- /dev/null +++ b/frontend/docs/_sidebar.md @@ -0,0 +1,12 @@ +- [Get Started](/README.md) + + + + + +- [Git Commands](./documents/gitNotes.md) +- [Notes and Guidlines](./documents/notes.md) +- [Basic Project Structure](./documents/projectStructure.md) +- [How to Document](./documents/documentationGuide.md) +- [How to Write a Markdown (.md)](./documents/markdownGuide.md) +- [Docsify Overview](./documents/docsifyGuide.md) diff --git a/frontend/docs/assets/images/gitBranching.svg b/frontend/docs/assets/images/gitBranching.svg new file mode 100644 index 0000000..da05643 --- /dev/null +++ b/frontend/docs/assets/images/gitBranching.svg @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/docs/assets/images/gitWorkFlow.svg b/frontend/docs/assets/images/gitWorkFlow.svg new file mode 100644 index 0000000..da967f0 --- /dev/null +++ b/frontend/docs/assets/images/gitWorkFlow.svg @@ -0,0 +1,10 @@ + + + + + + + + WorkspaceStaging areaLocal repositoryRemote repositorygit add .git commit -m "message"git pushgit fetchgit pull \ No newline at end of file diff --git a/frontend/docs/assets/images/projectFlow.svg b/frontend/docs/assets/images/projectFlow.svg new file mode 100644 index 0000000..9633fc4 --- /dev/null +++ b/frontend/docs/assets/images/projectFlow.svg @@ -0,0 +1,10 @@ + + + + + + + + Get startedSign inSign upDashboardFloorplan BuilderReal-Time Interface BuilderAction BuilderScene / New Scene / Shared SceneSimulation BuilderDraw wallUpload FloorplanCreate zones / sectionsAdd AssetsAdd FenestrationDraw Aisle / markingsAdd ColumnsAdd FloorAdd RoofAdd UI ( 3D/2D )Connect DataPreview DataDwinzo v 0.4Dwinzo v 1.0Dwinzo v 2.0Dwinzo v 2.4Dwinzo v 3.0Dwinzo v 4.0Edit AnimationAdd AnimationSimple AnimationAdvansed AnimationData Analysis / PredictionROImorePath SimulationProduction capacity / efficiencyWorkspace analysisEnvironment visualizerProcess AnalyserThroughput timePhysicsVisualizer(Organization module)InterpolationsEasingArmature ( bones / rigs )Shape manipulation \ No newline at end of file diff --git a/frontend/docs/assets/videos/dwinzo_version-0.0-refrence/realtime visualization.mp4 b/frontend/docs/assets/videos/dwinzo_version-0.0-refrence/realtime visualization.mp4 new file mode 100644 index 0000000..8159360 Binary files /dev/null and b/frontend/docs/assets/videos/dwinzo_version-0.0-refrence/realtime visualization.mp4 differ diff --git a/frontend/docs/assets/videos/dwinzo_version-0.0-refrence/walkthrough.mp4 b/frontend/docs/assets/videos/dwinzo_version-0.0-refrence/walkthrough.mp4 new file mode 100644 index 0000000..da2d208 Binary files /dev/null and b/frontend/docs/assets/videos/dwinzo_version-0.0-refrence/walkthrough.mp4 differ diff --git a/frontend/docs/documents/docsifyGuide.md b/frontend/docs/documents/docsifyGuide.md new file mode 100644 index 0000000..c4a90f6 --- /dev/null +++ b/frontend/docs/documents/docsifyGuide.md @@ -0,0 +1,35 @@ +# Quick start + +It is recommended to install `docsify-cli` globally, which helps initializing and previewing the website locally. + +```bash +npm i docsify-cli -g +``` + +### Initialize + +If you want to write the documentation in the `./docs` subdirectory, you can use the `init` command. + +```bash +docsify init ./docs +``` + +### Writing content + +After the `init` is complete, you can see the file list in the `./docs` subdirectory. + +- `index.html` as the entry file +- `README.md` as the home page +- `.nojekyll` prevents GitHub Pages from ignoring files that begin with an underscore + +You can easily update the documentation in `./docs/README.md`, of course you can add more pages. + +### Preview your site + +Run the local server with `docsify serve`. You can preview your site in your browser on `http://localhost:3000`. + +```bash +docsify serve docs +``` + +?> For more use cases of `docsify-cli`, head over to the [docsify-cli documentation](https://github.com/docsifyjs/docsify-cli). \ No newline at end of file diff --git a/frontend/docs/documents/documentationGuide.md b/frontend/docs/documents/documentationGuide.md new file mode 100644 index 0000000..b189a25 --- /dev/null +++ b/frontend/docs/documents/documentationGuide.md @@ -0,0 +1,380 @@ +# Why Documentation is Important for Developers + +Documentation helps developers work efficiently and ensures projects run smoothly. Here’s why it’s crucial: + +1. **Knowledge Sharing**: It helps team members understand the system and communicate effectively, especially when new people join the project. + +2. **Code Maintenance**: Good documentation makes it easier to fix bugs, make updates, and keep the code consistent. + +3. **Project Longevity**: It ensures that project knowledge is preserved, so future developers can maintain or improve the code without confusion. + +4. **Troubleshooting**: Developers can quickly find solutions to problems or understand past decisions, saving time and reducing errors. + +5. **Testing and Quality**: Documentation helps ensure the right testing processes are followed, leading to better-quality code. + +6. **Efficiency**: It saves time by reducing the need to explain things repeatedly or search for answers. + +In short, internal documentation keeps projects organized, helps teams collaborate, and ensures the software can be maintained and improved over time. + +--- + +## Guide to Writing Modular Documentation for React Projects + +Modular documentation refers to organizing your documentation into independent, reusable sections or modules. Each module typically covers a specific part of your project, making it easier to update and navigate. + +In the context of React, modular documentation should cover both React components and the overall architecture of the app. + +### Split Documentation into Smaller Sections + +When documenting, break down each part of your codebase into its smallest logical unit: + +1. **Functions**: Explain its purpose, inputs (arguments), and outputs (returns). +2. **Components**: Detail props, their types, default values, and the UI they render. +3. **Utilities/Helpers**: Document what a utility does, its inputs, and outputs. +4. **APIs**: Cover the endpoint, request format, and expected response. + +Each section should have a consistent structure for easy understanding and reference. + +## Documenting Functions + +#### Structure for Documenting Functions + +1. **Function Name**: A short and descriptive name. +2. **Purpose**: Briefly explain what the function does. +3. **Inputs**: + - List each parameter. + - Include types and default values if applicable. +4. **Output**: Describe the return value and its type. +5. **Code Examples**: Provide a usage example. + +#### Example: Utility Function Documentation + +````markdown +## `formatDate` + +### Purpose + +The `formatDate` function converts a `Date` object into a human-readable string format. + +### Inputs + +| Parameter | Type | Default Value | Description | +| --------- | -------- | ------------- | -------------------------- | +| `date` | `Date` | - | The date object to format. | +| `locale` | `string` | `"en-US"` | The locale for formatting. | + +### Output + +Returns a `string` representing the formatted date. + +### Example + +```javascript +import { formatDate } from "./utils"; + +const date = new Date("2024-11-21"); +console.log(formatDate(date)); // Output: "November 21, 2024" +``` +```` + +## Documenting Components + +#### Structure for Documenting Components + +1. **Component Name**: Name of the React component. +2. **Purpose**: Explain what the component is for and its use case. +3. **Props**: + - List each prop. + - Include type, whether it’s required, and default value. +4. **Behavior**: Describe what the component does and any side effects. +5. **Output**: Explain what the component renders or returns. +6. **Code Examples**: Show how to use the component. + +#### Example: Component Documentation + +`````markdown +## `Button` + +### Purpose + +The `Button` component renders a clickable button with customizable styles and behavior. + +### Props + +| Prop Name | Type | Required | Default Value | Description | +| ---------- | ---------- | -------- | ------------- | ---------------------------------- | +| `label` | `string` | Yes | - | The text displayed on the button. | +| `onClick` | `function` | No | `() => {}` | The function to call when clicked. | +| `disabled` | `boolean` | No | `false` | Disables the button if true. | +| `style` | `object` | No | `{}` | Inline styles for the button. | + +### Behavior + +- If `disabled` is true, the button cannot be clicked. +- The `onClick` function will only be called when the button is enabled. + +### Output + +Renders a `; + }; + + export default Button; + ``` + +2. **Functions**: + + - Include a **detailed description** of what the function does. + - Specify the **parameters**, their types, and what they represent. + - Specify the **return type** and what it represents. + + **Example**: + + ```ts + /** + * Converts a date string to a readable format. + * + * @param {string} date - A date string in ISO format (e.g., "2024-11-21"). + * @returns {string} The formatted date (e.g., "November 21, 2024"). + */ + export const formatDate = (date: string): string => { + const options: Intl.DateTimeFormatOptions = { + year: "numeric", + month: "long", + day: "numeric", + }; + return new Date(date).toLocaleDateString(undefined, options); + }; + ``` + +3. **Commenting Standards**: + + - Each function and component should have a comment explaining: + - What it does. + - The props or parameters it accepts (including types). + - What it returns and why. + +4. **Why This Matters**: + - This structure helps us maintain a clean, modular codebase. It also makes the project easier to navigate for new and existing team members. + +--- + +## File Naming Guidelines + +To maintain consistency and professionalism in our codebase, we are standardizing the way we name files. This is crucial for readability, collaboration, and avoiding potential issues across different operating systems. +We are introducing a standardized **file naming convention** to maintain consistency across the codebase. Here are the key points: + +1. **File Naming**: + + - All file names must follow the **camelCase** convention (e.g., `headerComponent.tsx`, `calculateTotal.ts`). + - This ensures uniformity and avoids case sensitivity issues. + +2. **Pre-Commit Hook**: + + - A pre-commit hook will automatically rename files to camelCase if they don’t comply. + - Please double-check that your imports match the updated file names to avoid runtime errors. + +3. **What You Need to Do**: + + - Name files correctly in camelCase from the start. + - If a file is renamed during a commit, ensure all imports are updated to reflect the new name. + +4. **Why This Matters**: + - Consistent file naming improves readability and reduces issues when working in teams or across different operating systems. diff --git a/frontend/docs/documents/projectStructure.md b/frontend/docs/documents/projectStructure.md new file mode 100644 index 0000000..a289618 --- /dev/null +++ b/frontend/docs/documents/projectStructure.md @@ -0,0 +1,97 @@ +## Project Folder Structure + +```plaintext +my-react-app/ +├── .github/ +│ └── workflows/ # CI/CD configuration (e.g., GitHub Actions) +│ └── ci.yml # Configuration for automated tests/lints +├── .husky/ # Husky Git hooks +│ ├── pre-commit # Pre-commit hook for linting and tests +│ ├── pre-push # Pre-push hook for running tests +│ └── _/ # Husky internal scripts +│ └── husky.sh # Husky script +├── docs/ # Documentation folder (for Docsify) +│ ├── _navbar.md # Navigation configuration for Docsify +│ ├── documentation # Documented contents +│ ├── _sidebar.md # Sidebar configuration for Docsify +│ ├── .nojekyll # Skip Jekyll processing for GitHub Pages +│ ├── index.html # Main landing page for Docsify +│ └── README.md # Documentation file +├── public/ # Static public assets (e.g., index.html) +├── src/ # Main source code +│ ├── assets/ # Static assets (images, styles) +│ │ ├── fonts/ # Font files +│ │ ├── images/ # Image files +│ │ ├── models/ # 3d files (e.g., .gltf, .fbx) +│ │ └── styles/ # Global styles (SCSS) +│ │ ├── abstracts/ # SCSS variables, functions, and mixins +│ │ ├── base/ # Basic, global styles (e.g., resets) +│ │ ├── components/ # Styles specific to components +│ │ ├── layout/ # Layout-related styles (e.g., grid, flexbox) +│ │ ├── pages/ # Page-specific styles +│ │ └── main.scss # Main SCSS entry file +│ ├── components/ # Reusable React components +│ │ ├── 3d-ui/ # 3d ui components (e.g., distance text) +│ │ ├── common/ # Shared/common components (e.g., buttons, inputs) +│ │ ├── layout/ # Layout-related components (e.g., header, footer) +│ │ ├── ui/ # Ui-related components (e.g., toolbar, menu) +│ │ ├── templates/ # modals, loaders, skeletons +│ │ ├── temp/ # temporary workspace (to try function/components without interfearing with app) +│ │ └── scene/ # all 3d realted functions. +│ ├── hooks/ # Custom React hooks +│ ├── functions/ # Non-React utility functions +│ ├── pages/ # Page components (e.g., Home, About) +│ ├── services/ # API services and business logic +│ ├── store/ # Global state management (e.g., Redux store) +│ ├── store/ # Global state management (e.g., Redux store) +│ ├── temp/ # temporary workspace (to try function/components without interfearing with app) +│ ├── tests/ # Testing folder +│ │ ├── unit/ # Unit tests +│ │ │ ├── __mocks__/ # Mock files for unit tests +│ │ │ ├── __tests__/ # Unit test files +│ │ │ ├── setupTests.ts # Setup for Jest +│ │ │ └── jest.config.js # Jest configuration +│ │ └── e2e/ # End-to-end tests (Cypress) +│ │ ├── integration/ # Integration test files +│ │ ├── fixtures/ # Fixtures for mock data in tests +│ │ ├── plugins/ # Cypress plugins +│ │ ├── support/ # Cypress support files (e.g., commands) +│ │ └── cypress.config.js # Cypress configuration +│ ├── utils/ # Utility functions/helpers (independent functions) +│ ├── app.tsx # Root React component +│ ├── index.tsx # Main entry point for React application +│ └── react-app-env.d.ts # TypeScript environment types for React +├── .env # Environment variables (e.g., API keys) +├── .eslintrc.js # ESLint configuration for code linting +├── .gitignore # Files and directories to be ignored by Git +├── package.json # Project dependencies and scripts +├── tsconfig.json # TypeScript configuration +└── README.md # Project documentation (this file) +``` + +## Planed Project Flow + +

+ Git basic Workflow +

+ +## Google Documents Links + +1. 📄 [Factory Builder Feature explanation](https://docs.google.com/document/d/1yDu-kfRFhQVOx2ydcaaA5nZJ3itdc6JKa9SU7wlXGUU/edit?tab=t.0) + +2. 📄 [Real-Time Visualization Editor](https://docs.google.com/document/d/1DVkM2h1KVYorbUUtSHDBbSyGkwel-Z-TX6nT9pHLs1o/edit?tab=t.0#heading=h.s6jrhhnl6xzz) + +3. 📄 [Action Builder](https://docs.google.com/document/d/1q-vzbUcH5K2sDOm-Aiw0jJ4QYYP6wT4MXXGs2UKQqBs/edit?tab=t.0#heading=h.h5m0upm9zsk9) + +4. 📄 [MarketPlace Modelling Documentation](https://docs.google.com/document/d/1I7pCqVlCODtThqipb_wWGG5vP0_Hc_xZQQIqoD4bN-w/edit?tab=t.0) + +5. 📄 [Component : Outliner](https://docs.google.com/document/d/1EeKPSCYBY9rB9V7glZWpI5C0iJDn25yb4yTHRG2AFzE/edit?tab=t.0) + +## Refrence videos + +1. This video offers a preview of a conceptual project created entirely with Figma and Blender based on previous version of this project (Dwinzo). + + diff --git a/frontend/docs/documents/projectVision.md b/frontend/docs/documents/projectVision.md new file mode 100644 index 0000000..7423a8b --- /dev/null +++ b/frontend/docs/documents/projectVision.md @@ -0,0 +1,153 @@ +## Intoduction + +**Imagine a world where industries no longer have to rely solely on theoretical calculations to make critical decisions.** + +A factory manager at a bustling automotive plant is faced with a challenge. The current production floor layout seems inefficient, but overhauling it physically is expensive, time-consuming, and risky. Traditional math-based analysis feels abstract and doesn’t give a clear, visual understanding of potential improvements. This is where this Web-Based Digital Twin Builder and Real-Time Monitoring System, **Dwinzo** steps in to transform decision-making. + +--- + +## The Scope and Vision + +This web-based platform is **more than just software**; it’s a gateway to a fully virtualized, predictive world. Designed to cater to **large-scale industries**, it empowers managers, engineers, and decision-makers to effortlessly **visualize, simulate, and monitor their operations digitally**. Yet, it is versatile enough to cater to individuals, allowing even hobbyists to create **home automation systems** or small-scale monitoring solutions. + +By bridging the gap between theoretical models and physical execution, this platform brings the power of **simulation, real-time analytics, and physics-based predictions** directly into user's hands without the need for complex hardware setups. + +--- + +## How It Solves Problems + +Large industries face high stakes when implementing changes to layouts or workflows. Errors in planning can lead to **downtime, wasted resources, and financial losses**. + +this platform revolutionizes this process by enabling users to: + +- **Draw or import layouts**, crafting digital twins of their facilities with precision. +- Assemble and arrange **assets or machinery** in the virtual environment, creating a clear, visual representation of proposed changes. +- Simulate various workflows and scenarios to understand **real-world implications** of decisions before making costly commitments. +- Compare multiple layouts or simulations side by side to select the optimal solution based on **ROI, production capacity, or other metrics**. + +No more guesswork. No more expensive trial-and-error. + +--- + +## Key Features + +1. **Interactive Building Tools:** + Users can start from scratch with intuitive tools to draw blueprints or directly import existing layouts, saving time and effort. + +2. **Asset Assembly and Customization:** + The platform allows assets like machinery, sensors, or furniture to be placed and configured based on visual assumptions or exact specifications. + +3. **Scenario Simulation:** + From workflow analysis to capacity simulations, users can create **"what-if" scenarios** to predict outcomes and identify bottlenecks. + +4. **Customizable Real-Time Displays:** + Monitoring dashboards can be tailored to show only the data most relevant to the user, enhancing clarity and focus. + +5. **Web-Based Accessibility:** + Without requiring specialized hardware, the platform is accessible from anywhere, ensuring maximum convenience and usability. + +--- + +## What Makes It Unique? + +While competitors often rely on physical devices to bridge the digital and physical realms, this solution bypasses this barrier with its **purely web-based approach**. No need for expensive sensors, cameras, or hardware installations. Users can dive straight into the digital twin world with just a browser and internet access, making it not only **cost-effective** but also **globally scalable**. + +--- + +## Example Analysis: Optimizing a Pipe Manufacturing Facility Using Dwinzo + +#### Scenario Overview + +A pipe manufacturing plant is experiencing inefficiencies in its production workflow. The plant's management team wants to assess whether rearranging machinery and material flow could increase output and reduce bottlenecks. However, conducting physical trials for these changes would disrupt operations and risk costly downtime. + +The team decides to use a **web-based digital twin builder and real-time monitoring system** to analyze potential solutions in a virtual environment before implementing changes on the shop floor. + +### Step 1: Building the Digital Twin + +The team begins by creating a digital replica of the plant. Using the platform’s tools, they: + +- **Import the factory’s layout** from CAD files, including walls, doors, and pathways. +- Place **assets** such as cutting machines, welding stations, and inspection equipment into their respective locations. +- Configure the material flow routes, worker stations, and raw material storage zones. + +This setup takes only a few hours, thanks to the platform’s intuitive interface and drag-and-drop tools. + +### Step 2: Identifying the Problem Areas + +The digital twin is configured to simulate the factory's current workflow. Key inefficiencies identified include: + +1. **Long Material Travel Distances:** Pipes must traverse a lengthy path from raw material storage to cutting machines, leading to delays. +2. **Bottlenecks at Welding Stations:** Due to a mismatch in capacity, finished parts pile up at welding stations, slowing the entire production line. +3. **Underutilized Space:** Certain areas of the factory floor remain unused, while others are overcrowded. + +### Step 3: Testing Solutions + +The team simulates multiple scenarios using the digital twin. Examples include: + +1. **Rearranging Machines to Reduce Material Travel Time:** + + - Cutting machines are moved closer to the raw material storage zone. + - Conveyor belts are re-routed to minimize transportation distance. + - Simulation Result: Material travel distance is reduced by 40%, speeding up the overall process. + +2. **Adding a New Welding Station to Eliminate Bottlenecks:** + + - A third welding station is added, balancing the capacity of upstream and downstream operations. + - Simulation Result: Waiting times at welding stations drop by 60%, increasing production throughput. + +3. **Optimizing Unused Space for Worker Movement:** + - Worker pathways are redesigned, improving accessibility to machines without crossing high-traffic areas. + - Simulation Result: Worker efficiency improves by 15%, reducing delays during material handling. + +### Step 4: Visualizing the Best Layout + +The platform provides a visual comparison of all tested scenarios, displaying key metrics such as: + +- Time savings for material transport. +- Reduction in bottleneck durations. +- Space utilization improvements. + +The team selects the layout with the most balanced improvements across all metrics. + +### Step 5: Monitoring and Implementation + +Once the optimized layout is chosen, the team uses the platform’s **real-time monitoring tools** during implementation to track progress. Key steps include: + +- Monitoring machine performance to ensure the relocation doesn’t introduce new issues. +- Tracking production metrics to validate improvements predicted by the simulation. +- Adjusting worker schedules to adapt to the new layout. + +### Conclusion of this analysis + +By simulating and analyzing these scenarios in a virtual environment, the management team avoids unnecessary disruption to the factory’s operations. The digital twin application provides actionable insights into how to optimize layout, workflows, and capacity without relying on risky physical trials. + +This example demonstrates how the application can be used to **proactively solve operational problems**, reduce risks, and make data-driven decisions in industries like pipe manufacturing. + +--- + +## The Long-Term Vision + +this project aims to be the cornerstone of the **digital transformation** revolution. By bringing processes, layouts, and workflows into a fully virtualized space, you reduce the risks associated with physical errors and empower users to: + +- Achieve **greater security and monitoring**. +- Make **smarter, data-driven decisions**. +- Embrace a future where **everything can be planned, tested, and optimized digitally** before taking a single physical action. + +Imagine a future where industries, homes, and cities alike are interconnected in a seamless digital ecosystem. From ensuring worker safety to minimizing operational inefficiencies, this platform is poised to create a **safer, smarter, and more efficient world**. + +--- + +## Summary + +This project is a **web-based digital twin builder and real-time monitoring system** that allows users to: + +1. **Create and visualize** virtual replicas (digital twins) of buildings, layouts, or workflows. +2. **Simulate scenarios** and analyze data (e.g., ROI, production capacity) to optimize processes. +3. Monitor real-time data with **customizable dashboards** for better decision-making. + +Its **main audience** includes **large-scale industries**, though it can also cater to smaller use cases like **home automation**. It addresses the problem of inefficient, theoretical decision-making by providing an **accessible, hardware-free, simulation-driven approach** to test and verify workflows digitally. + +The platform is unique because it’s **web-based**, removing the need for physical hardware, and aims to bring security, monitoring, and simulation into the digital world to **reduce risks and improve efficiency**. + + diff --git a/frontend/docs/index.html b/frontend/docs/index.html new file mode 100644 index 0000000..5dcb9ac --- /dev/null +++ b/frontend/docs/index.html @@ -0,0 +1,97 @@ + + + + + + Documentation + + + + + + + + + + + +
+ + + + + + + + + + + + + + diff --git a/frontend/docs/styles/style.css b/frontend/docs/styles/style.css new file mode 100644 index 0000000..53546bb --- /dev/null +++ b/frontend/docs/styles/style.css @@ -0,0 +1,135 @@ +/* Default light theme (comes from the vue.css theme) */ + +/* Dark theme styles */ +body.dark-theme { + background-color: #323232; + color: #f2f2f2; +} +body.dark-theme .sidebar-toggle span { + background-color: #127efa; +} +body.dark-theme .markdown-section code, +body.dark-theme .markdown-section pre { + background-color: #131313; + color: #f2f2f2; +} + +/* Sidebar Dark Mode */ +body.dark-theme .sidebar { + background-color: #131313; + color: #f2f2f2; +} +body.dark-theme .sidebar ul li a { + color: #f2f2f2; +} +body.dark-theme .anchor span { + color: #f2f2f2; +} +body.dark-theme .sidebar ul li.active > a { + color: #1e90ff; +} + +/* Change link colors in dark theme */ +body.dark-theme a { + color: #1e90ff; +} + +/* Customize header (if needed) */ +body.dark-theme .header { + background-color: #232323; + color: #f2f2f2; +} + +/* Optional: Customize any other element */ +body.dark-theme .content { + background-color: #323232; + color: #f2f2f2; + font-weight: 100; +} + +body.dark-theme .markdown-section h1, +body.dark-theme .markdown-section h2, +body.dark-theme .markdown-section h3, +body.dark-theme .markdown-section h4, +body.dark-theme .markdown-section strong { + color: #e3e3e3; + font-weight: 600; +} + +body.dark-theme .sidebar ul li a:hover::after { + background-color: #323232; +} + +/* Other over written styles */ + +.sidebar-toggle { + background: transparent; +} +.markdown-section code, +.markdown-section pre { + border-radius: 8px; +} +.markdown-section code::after, +.markdown-section pre::after { + display: none; +} +.content { + padding-top: 14px; +} + +.sidebar-toggle { + top: 0; + height: fit-content; + width: fit-content; +} +.theme-toggle-container { + position: fixed; + top: 8px; + left: 38px; + z-index: 50; + display: flex; + align-items: center; +} +.theme-toggle-container button { + background-color: transparent; + border: none; + cursor: pointer; +} + +.sidebar ul { + margin: 0; + /* padding: 0 0 0 15px; */ +} +.sidebar li { + padding: 0 0 0 15px; + margin: 0; +} + +.sidebar ul li a:hover { + text-decoration: none; +} + +.sidebar ul li a:hover::after { + content: ""; + width: 100%; + position: absolute; + left: 0; + height: 30px; + background-color: #e5ebec; + z-index: -1; +} +.app-nav.no-badge { + margin: 8px; +} +.app-nav.no-badge ul { + padding: 0; + padding-right: 6px; +} + +video { + border-radius: 8px; + border: none; + outline: none; + margin: 0; + padding: 0; +} diff --git a/frontend/git b/frontend/git new file mode 100644 index 0000000..e69de29 diff --git a/frontend/nginx.conf b/frontend/nginx.conf new file mode 100644 index 0000000..a6265e3 --- /dev/null +++ b/frontend/nginx.conf @@ -0,0 +1,14 @@ +server { + listen 3000; + server_name localhost; + + root /usr/share/nginx/html; + index index.html; + + location / { + try_files $uri /index.html; + } + + # Redirect 404 errors to index.html (for React Router) + error_page 404 /index.html; +} \ No newline at end of file diff --git a/frontend/package-lock.json b/frontend/package-lock.json new file mode 100644 index 0000000..c002157 --- /dev/null +++ b/frontend/package-lock.json @@ -0,0 +1,22776 @@ +{ + "name": "dwinzo-app", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "dwinzo-app", + "version": "0.1.0", + "dependencies": { + "@dnd-kit/core": "^6.3.1", + "@dnd-kit/sortable": "^10.0.0", + "@react-three/csg": "^3.2.0", + "@react-three/drei": "^9.113.0", + "@react-three/fiber": "^8.17.7", + "@react-three/postprocessing": "^2.16.3", + "@testing-library/jest-dom": "^5.17.0", + "@testing-library/react": "^13.4.0", + "@testing-library/user-event": "^13.5.0", + "@turf/turf": "^7.1.0", + "@types/jest": "^27.5.2", + "@types/react": "^18.3.5", + "@types/react-dom": "^18.3.0", + "@use-gesture/react": "^10.3.1", + "chart.js": "^4.4.8", + "glob": "^11.0.0", + "gsap": "^3.12.5", + "leva": "^0.10.0", + "mqtt": "^5.10.3", + "postprocessing": "^6.36.4", + "prompt-sync": "^4.2.0", + "react": "^18.3.1", + "react-beautiful-dnd": "^13.1.1", + "react-dom": "^18.3.1", + "react-easy-sort": "^1.6.0", + "react-router-dom": "^7.0.1", + "react-scripts": "5.0.1", + "react-sortablejs": "^6.1.4", + "react-toastify": "^10.0.5", + "recharts": "^2.15.1", + "sass": "^1.78.0", + "socket.io-client": "^4.8.1", + "sortablejs": "^1.15.6", + "three": "^0.168.0", + "typescript": "^4.9.5", + "uuid": "^11.1.0", + "web-vitals": "^2.1.4", + "zustand": "^5.0.0-rc.2" + }, + "devDependencies": { + "@types/node": "^22.9.1", + "@types/three": "^0.169.0", + "cypress": "^13.14.2", + "dotenv": "^16.4.5", + "husky": "^9.1.6", + "ts-node": "^10.9.2" + } + }, + "node_modules/@adobe/css-tools": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz", + "integrity": "sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==" + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.0.tgz", + "integrity": "sha512-INCKxTtbXtcNbUZ3YXutwMpEleqttcswhAdee7dhuoVrD2cnuc3PqtERBtxkX5nziX9vnBL8WXmSGwv8CuPV6g==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.0.tgz", + "integrity": "sha512-qETICbZSLe7uXv9VE8T/RWOdIE5qqyTucOt4zLYMafj2MRO271VGgLd4RACJMeBO37UPWhXiKMBk7YlJ0fOzQA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/eslint-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.25.9.tgz", + "integrity": "sha512-5UXfgpK0j0Xr/xIdgdLEhOFxaDZ0bRPWJJchRpqOSur/3rZoPbqqki5mm0p4NE2cs28krBEiSM2MB7//afRSQQ==", + "dependencies": { + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || >=14.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0", + "eslint": "^7.5.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/@babel/eslint-parser/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@babel/eslint-parser/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.0.tgz", + "integrity": "sha512-/AIkAmInnWwgEAJGQr9vY0c66Mj6kjkE2ZPB1PurTRaRAh3U+J45sAQMjQDJdh4WbR3l0x5xkimXBKyBXXAu2w==", + "dependencies": { + "@babel/parser": "^7.26.0", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.9.tgz", + "integrity": "sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g==", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "dependencies": { + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.9.tgz", + "integrity": "sha512-ORPNZ3h6ZRkOyAa/SaHU+XsLZr0UQzRwuDQ0cczIA17nAzZ+85G5cVkOJIj7QavLZGSe8QXUmNFxSZzjcZF9bw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", + "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz", + "integrity": "sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.1.tgz", + "integrity": "sha512-reoQYNiAJreZNsJzyrDNzFQ+IQ5JFiIzAHJg9bn94S3l+4++J7RsIhNMoB+lgP/9tpmiAQqspv+xfdxTSzREOw==", + "dependencies": { + "@babel/types": "^7.26.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.25.9.tgz", + "integrity": "sha512-smkNLL/O1ezy9Nhy4CNosc4Va+1wo5w4gzSZeLe6y6dM4mmHfYOCPolXQPHQxonZCF+ZyebxN9vqOolkYrSn5g==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-syntax-decorators": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.25.9.tgz", + "integrity": "sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-flow": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.26.0.tgz", + "integrity": "sha512-B+O2DnPc0iG+YXFqOxv2WNuNU97ToWjOomUQ78DouOENWUaM5sVrmet9mcomUGQFwpJd//gvUagXBSdzO1fRKg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", + "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", + "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", + "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz", + "integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.9.tgz", + "integrity": "sha512-KRhdhlVk2nObA5AYa7QMgTMTVJdfHprfpAk4DjZVtllqRg9qarilstTKEhpVjyt+Npi8ThRyiV8176Am3CodPA==", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-flow-strip-types": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.25.9.tgz", + "integrity": "sha512-/VVukELzPDdci7UUsWQaSkhgnjIWXnIyRpM02ldxaVoFK96c41So8JcKT3m0gYjyv7j5FNPGS5vfELrWalkbDA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-syntax-flow": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", + "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.9.tgz", + "integrity": "sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg==", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-simple-access": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz", + "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.25.9.tgz", + "integrity": "sha512-Ncw2JFsJVuvfRsa2lSHiC55kETQVLSnsYGQ1JDDwkUeWGTL/8Tom8aLTnlqgoeuopWrbbGndrc9AlLYrIosrow==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.25.9.tgz", + "integrity": "sha512-KJfMlYIUxQB1CJfO3e0+h0ZHWOTLCPP115Awhaz8U0Zpq36Gl/cXlpoyMRnUWlhNUBAzldnCiAZNvCDj7CrKxQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.9.tgz", + "integrity": "sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.25.9.tgz", + "integrity": "sha512-9mj6rm7XVYs4mdLIpbZnHOYdpW42uoiBCTVowg7sP1thUOiANgMb4UtpRivR0pp5iL+ocvUv7X4mZgFRpJEzGw==", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.25.9.tgz", + "integrity": "sha512-KQ/Takk3T8Qzj5TppkS1be588lkbTp5uj7w6a0LeQaTMSckU/wK0oJ/pih+T690tkgI5jfmg2TqDJvd41Sj1Cg==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz", + "integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", + "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", + "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.9.tgz", + "integrity": "sha512-7PbZQZP50tzv2KGGnhh82GSyMB01yKY9scIjf1a+GfZCtInOWqUH5+1EBU4t9fyR5Oykkkc9vFTs4OHrhHXljQ==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-syntax-typescript": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", + "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", + "dependencies": { + "@babel/compat-data": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.25.9", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", + "@babel/plugin-transform-classes": "^7.25.9", + "@babel/plugin-transform-computed-properties": "^7.25.9", + "@babel/plugin-transform-destructuring": "^7.25.9", + "@babel/plugin-transform-dotall-regex": "^7.25.9", + "@babel/plugin-transform-duplicate-keys": "^7.25.9", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-dynamic-import": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.25.9", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-function-name": "^7.25.9", + "@babel/plugin-transform-json-strings": "^7.25.9", + "@babel/plugin-transform-literals": "^7.25.9", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", + "@babel/plugin-transform-member-expression-literals": "^7.25.9", + "@babel/plugin-transform-modules-amd": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-modules-systemjs": "^7.25.9", + "@babel/plugin-transform-modules-umd": "^7.25.9", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-new-target": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9", + "@babel/plugin-transform-numeric-separator": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-object-super": "^7.25.9", + "@babel/plugin-transform-optional-catch-binding": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-property-literals": "^7.25.9", + "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", + "@babel/plugin-transform-reserved-words": "^7.25.9", + "@babel/plugin-transform-shorthand-properties": "^7.25.9", + "@babel/plugin-transform-spread": "^7.25.9", + "@babel/plugin-transform-sticky-regex": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.25.9", + "@babel/plugin-transform-typeof-symbol": "^7.25.9", + "@babel/plugin-transform-unicode-escapes": "^7.25.9", + "@babel/plugin-transform-unicode-property-regex": "^7.25.9", + "@babel/plugin-transform-unicode-regex": "^7.25.9", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.38.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.25.9.tgz", + "integrity": "sha512-D3to0uSPiWE7rBrdIICCd0tJSIGpLaaGptna2+w7Pft5xMqLpA1sz99DK5TZ1TjGbdQ/VI1eCSZ06dv3lT4JOw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-transform-react-display-name": "^7.25.9", + "@babel/plugin-transform-react-jsx": "^7.25.9", + "@babel/plugin-transform-react-jsx-development": "^7.25.9", + "@babel/plugin-transform-react-pure-annotations": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz", + "integrity": "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-typescript": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@csstools/normalize.css": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.1.1.tgz", + "integrity": "sha512-YAYeJ+Xqh7fUou1d1j9XHl44BmsuThiTr4iNrgCQ3J27IbhXsxXDGZ1cXv8Qvs99d4rBbLiSKy3+WZiet32PcQ==" + }, + "node_modules/@csstools/postcss-cascade-layers": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz", + "integrity": "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==", + "dependencies": { + "@csstools/selector-specificity": "^2.0.2", + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-color-function": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz", + "integrity": "sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-font-format-keywords": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz", + "integrity": "sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-hwb-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz", + "integrity": "sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-ic-unit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz", + "integrity": "sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz", + "integrity": "sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==", + "dependencies": { + "@csstools/selector-specificity": "^2.0.0", + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-nested-calc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz", + "integrity": "sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-normalize-display-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz", + "integrity": "sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-oklab-function": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz", + "integrity": "sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-progressive-custom-properties": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz", + "integrity": "sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.3" + } + }, + "node_modules/@csstools/postcss-stepped-value-functions": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz", + "integrity": "sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-text-decoration-shorthand": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz", + "integrity": "sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-trigonometric-functions": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz", + "integrity": "sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-unset-value": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz", + "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==", + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", + "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss-selector-parser": "^6.0.10" + } + }, + "node_modules/@cypress/request": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.5.tgz", + "integrity": "sha512-v+XHd9XmWbufxF1/bTaVm2yhbxY+TB4YtWRqF2zaXBlDNMkls34KiATz0AVDLavL3iB6bQk9/7n3oY1EoLSWGA==", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~4.0.0", + "http-signature": "~1.4.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "performance-now": "^2.1.0", + "qs": "6.13.0", + "safe-buffer": "^5.1.2", + "tough-cookie": "^4.1.3", + "tunnel-agent": "^0.6.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@cypress/request/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@cypress/xvfb": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", + "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", + "dev": true, + "dependencies": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + } + }, + "node_modules/@cypress/xvfb/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@dnd-kit/accessibility": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz", + "integrity": "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/core": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz", + "integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==", + "license": "MIT", + "dependencies": { + "@dnd-kit/accessibility": "^3.1.1", + "@dnd-kit/utilities": "^3.2.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/sortable": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-10.0.0.tgz", + "integrity": "sha512-+xqhmIIzvAYMGfBYYnbKuNicfSsk4RksY2XdmJhT+HAC01nix6fHCztU68jooFiMUB01Ky3F0FyOvhG/BZrWkg==", + "license": "MIT", + "dependencies": { + "@dnd-kit/utilities": "^3.2.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@dnd-kit/core": "^6.3.0", + "react": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/utilities": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.2.tgz", + "integrity": "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.7.3.tgz", + "integrity": "sha512-buc8BXHmG9l82+OQXOFU3Kr2XQx9ys01U/Q9HMIrZ300iLc8HLMgh7dcCqgYzAzf4BkoQvDcXf5Y+CuEZ5JBYg==", + "license": "MIT" + }, + "node_modules/@floating-ui/dom": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.5.4.tgz", + "integrity": "sha512-419BMceRLq0RrmTSDxn8hf9R3VCJv2K9PUfugh5JyEFmdjzDo+e8U5EdR8nzKq8Yj1htzLm3b6eQEEam3/rrtg==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^0.7.3" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-0.7.2.tgz", + "integrity": "sha512-1T0sJcpHgX/u4I1OzIEhlcrvkUN8ln39nz7fMoE/2HDHrPiMFoOGR7++GYyfUmIQHkkrTinaeQsO3XWubjSvGg==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^0.5.3", + "use-isomorphic-layout-effect": "^1.1.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", + "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/core": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", + "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/reporters": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^27.5.1", + "jest-config": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-resolve-dependencies": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "jest-watcher": "^27.5.1", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", + "dependencies": { + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", + "dependencies": { + "@jest/types": "^27.5.1", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", + "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/types": "^27.5.1", + "expect": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", + "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@jest/reporters/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@jest/reporters/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@jest/reporters/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/schemas": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", + "dependencies": { + "@sinclair/typebox": "^0.24.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", + "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9", + "source-map": "^0.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/source-map/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/test-result": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", + "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", + "dependencies": { + "@jest/test-result": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-runtime": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/types": "^27.5.1", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/@jest/transform/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@kurkle/color": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", + "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==", + "license": "MIT" + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==" + }, + "node_modules/@mediapipe/tasks-vision": { + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/@mediapipe/tasks-vision/-/tasks-vision-0.10.8.tgz", + "integrity": "sha512-Rp7ll8BHrKB3wXaRFKhrltwZl1CiXGdibPxuWXvqGnKTnv8fqa/nvftYNuSbf+pbJWKYCXdBtYTITdAUTGGh0Q==" + }, + "node_modules/@monogrid/gainmap-js": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@monogrid/gainmap-js/-/gainmap-js-3.0.6.tgz", + "integrity": "sha512-ireqJg7cw0tUn/JePDG8rAL7RyXgUKSDbjYdiygkrnye1WuKGLAWDBwF/ICwCwJ9iZBAF5caU8gSu+c34HLGdQ==", + "dependencies": { + "promise-worker-transferable": "^1.0.4" + }, + "peerDependencies": { + "three": ">= 0.159.0" + } + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "dependencies": { + "eslint-scope": "5.1.1" + } + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.4.1.tgz", + "integrity": "sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==", + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.4.1", + "@parcel/watcher-darwin-arm64": "2.4.1", + "@parcel/watcher-darwin-x64": "2.4.1", + "@parcel/watcher-freebsd-x64": "2.4.1", + "@parcel/watcher-linux-arm-glibc": "2.4.1", + "@parcel/watcher-linux-arm64-glibc": "2.4.1", + "@parcel/watcher-linux-arm64-musl": "2.4.1", + "@parcel/watcher-linux-x64-glibc": "2.4.1", + "@parcel/watcher-linux-x64-musl": "2.4.1", + "@parcel/watcher-win32-arm64": "2.4.1", + "@parcel/watcher-win32-ia32": "2.4.1", + "@parcel/watcher-win32-x64": "2.4.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.4.1.tgz", + "integrity": "sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.4.1.tgz", + "integrity": "sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.4.1.tgz", + "integrity": "sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.4.1.tgz", + "integrity": "sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.4.1.tgz", + "integrity": "sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.4.1.tgz", + "integrity": "sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.4.1.tgz", + "integrity": "sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.4.1.tgz", + "integrity": "sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.4.1.tgz", + "integrity": "sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.4.1.tgz", + "integrity": "sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.4.1.tgz", + "integrity": "sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.4.1.tgz", + "integrity": "sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pmmmwh/react-refresh-webpack-plugin": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.15.tgz", + "integrity": "sha512-LFWllMA55pzB9D34w/wXUCf8+c+IYKuJDgxiZ3qMhl64KRMBHYM1I3VdGaD2BV5FNPV2/S2596bppxHbv2ZydQ==", + "dependencies": { + "ansi-html": "^0.0.9", + "core-js-pure": "^3.23.3", + "error-stack-parser": "^2.0.6", + "html-entities": "^2.1.0", + "loader-utils": "^2.0.4", + "schema-utils": "^4.2.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">= 10.13" + }, + "peerDependencies": { + "@types/webpack": "4.x || 5.x", + "react-refresh": ">=0.10.0 <1.0.0", + "sockjs-client": "^1.4.0", + "type-fest": ">=0.17.0 <5.0.0", + "webpack": ">=4.43.0 <6.0.0", + "webpack-dev-server": "3.x || 4.x || 5.x", + "webpack-hot-middleware": "2.x", + "webpack-plugin-serve": "0.x || 1.x" + }, + "peerDependenciesMeta": { + "@types/webpack": { + "optional": true + }, + "sockjs-client": { + "optional": true + }, + "type-fest": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + }, + "webpack-hot-middleware": { + "optional": true + }, + "webpack-plugin-serve": { + "optional": true + } + } + }, + "node_modules/@radix-ui/primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.0.tgz", + "integrity": "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.0.2.tgz", + "integrity": "sha512-fqYwhhI9IarZ0ll2cUSfKuXHlJK0qE4AfnRrPBbRwEH/4mGQn04/QFGomLi8TXWIdv9WJk//KgGm+aDxVIr1wA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.2" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz", + "integrity": "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.0.tgz", + "integrity": "sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.3.tgz", + "integrity": "sha512-nXZOvFjOuHS1ovumntGV7NNoLaEp9JEvTht3MBjP44NSW5hUKj/8OnfN3+8WmB+CEhN44XaGhpHoSsUIEl5P7Q==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-primitive": "1.0.2", + "@radix-ui/react-use-callback-ref": "1.0.0", + "@radix-ui/react-use-escape-keydown": "1.0.2" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.0.tgz", + "integrity": "sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.1.tgz", + "integrity": "sha512-keYDcdMPNMjSC8zTsZ8wezUMiWM9Yj14wtF3s0PTIs9srnEPC9Kt2Gny1T3T81mmSeyDjZxsD9N5WCwNNb712w==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@floating-ui/react-dom": "0.7.2", + "@radix-ui/react-arrow": "1.0.2", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-primitive": "1.0.2", + "@radix-ui/react-use-callback-ref": "1.0.0", + "@radix-ui/react-use-layout-effect": "1.0.0", + "@radix-ui/react-use-rect": "1.0.0", + "@radix-ui/react-use-size": "1.0.0", + "@radix-ui/rect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.2.tgz", + "integrity": "sha512-swu32idoCW7KA2VEiUZGBSu9nB6qwGdV6k6HYhUoOo3M1FFpD+VgLzUqtt3mwL1ssz7r2x8MggpLSQach2Xy/Q==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.2" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.0.tgz", + "integrity": "sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-use-layout-effect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.2.tgz", + "integrity": "sha512-zY6G5Qq4R8diFPNwtyoLRZBxzu1Z+SXMlfYpChN7Dv8gvmx9X3qhDqiLWvKseKVJMuedFeU/Sa0Sy/Ia+t06Dw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.1.tgz", + "integrity": "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.5.tgz", + "integrity": "sha512-cDKVcfzyO6PpckZekODJZDe5ZxZ2fCZlzKzTmPhe4mX9qTHRfLcKgqb0OKf22xLwDequ2tVleim+ZYx3rabD5w==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-dismissable-layer": "1.0.3", + "@radix-ui/react-id": "1.0.0", + "@radix-ui/react-popper": "1.1.1", + "@radix-ui/react-portal": "1.0.2", + "@radix-ui/react-presence": "1.0.0", + "@radix-ui/react-primitive": "1.0.2", + "@radix-ui/react-slot": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.0", + "@radix-ui/react-visually-hidden": "1.0.2" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz", + "integrity": "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.0.tgz", + "integrity": "sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.2.tgz", + "integrity": "sha512-DXGim3x74WgUv+iMNCF+cAo8xUHHeqvjx8zs7trKf+FkQKPQXLk2sX7Gx1ysH7Q76xCpZuxIJE7HLPxRE+Q+GA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz", + "integrity": "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.0.tgz", + "integrity": "sha512-TB7pID8NRMEHxb/qQJpvSt3hQU4sqNPM1VCTjTRjEOa7cEop/QMuq8S6fb/5Tsz64kqSvB9WnwsDHtjnrM9qew==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/rect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.0.0.tgz", + "integrity": "sha512-imZ3aYcoYCKhhgNpkNDh/aTiU05qw9hX+HHI1QDBTyIlcFjgeFlKKySNGMwTp7nYFLQg/j0VA2FmCY4WPDDHMg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.2.tgz", + "integrity": "sha512-qirnJxtYn73HEk1rXL12/mXnu2rwsNHDID10th2JGtdK25T9wX+mxRmGt7iPSahw512GbZOc0syZX1nLQGoEOg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.2" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.0.tgz", + "integrity": "sha512-d0O68AYy/9oeEy1DdC07bz1/ZXX+DqCskRd3i4JzLSTXwefzaepQrKjXC7aNM8lTHjFLDO0pDgaEiQ7jEk+HVg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@react-spring/animated": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.6.1.tgz", + "integrity": "sha512-ls/rJBrAqiAYozjLo5EPPLLOb1LM0lNVQcXODTC1SMtS6DbuBCPaKco5svFUQFMP2dso3O+qcC4k9FsKc0KxMQ==", + "dependencies": { + "@react-spring/shared": "~9.6.1", + "@react-spring/types": "~9.6.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/core": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.6.1.tgz", + "integrity": "sha512-3HAAinAyCPessyQNNXe5W0OHzRfa8Yo5P748paPcmMowZ/4sMfaZ2ZB6e5x5khQI8NusOHj8nquoutd6FRY5WQ==", + "dependencies": { + "@react-spring/animated": "~9.6.1", + "@react-spring/rafz": "~9.6.1", + "@react-spring/shared": "~9.6.1", + "@react-spring/types": "~9.6.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-spring/donate" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/rafz": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.6.1.tgz", + "integrity": "sha512-v6qbgNRpztJFFfSE3e2W1Uz+g8KnIBs6SmzCzcVVF61GdGfGOuBrbjIcp+nUz301awVmREKi4eMQb2Ab2gGgyQ==" + }, + "node_modules/@react-spring/shared": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.6.1.tgz", + "integrity": "sha512-PBFBXabxFEuF8enNLkVqMC9h5uLRBo6GQhRMQT/nRTnemVENimgRd+0ZT4yFnAQ0AxWNiJfX3qux+bW2LbG6Bw==", + "dependencies": { + "@react-spring/rafz": "~9.6.1", + "@react-spring/types": "~9.6.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/three": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@react-spring/three/-/three-9.6.1.tgz", + "integrity": "sha512-Tyw2YhZPKJAX3t2FcqvpLRb71CyTe1GvT3V+i+xJzfALgpk10uPGdGaQQ5Xrzmok1340DAeg2pR/MCfaW7b8AA==", + "dependencies": { + "@react-spring/animated": "~9.6.1", + "@react-spring/core": "~9.6.1", + "@react-spring/shared": "~9.6.1", + "@react-spring/types": "~9.6.1" + }, + "peerDependencies": { + "@react-three/fiber": ">=6.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "three": ">=0.126" + } + }, + "node_modules/@react-spring/types": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.6.1.tgz", + "integrity": "sha512-POu8Mk0hIU3lRXB3bGIGe4VHIwwDsQyoD1F394OK7STTiX9w4dG3cTLljjYswkQN+hDSHRrj4O36kuVa7KPU8Q==" + }, + "node_modules/@react-three/csg": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@react-three/csg/-/csg-3.2.0.tgz", + "integrity": "sha512-POnakTYaJqmqKsk9Q23oCL78JmaitN2+s/ciOHDK8dQu6GsSa2eMzlhR7J7kI9VdjmV/cW2cRz9XJEWNJ4XmfA==", + "dependencies": { + "three-bvh-csg": "^0.0.16", + "three-mesh-bvh": "^0.6.8" + } + }, + "node_modules/@react-three/drei": { + "version": "9.115.0", + "resolved": "https://registry.npmjs.org/@react-three/drei/-/drei-9.115.0.tgz", + "integrity": "sha512-VQN/AdTwLFAXEeZCCLhxGLaL5pUWt/qBOJEyr/CCgs4j/RIw1cS1CvRJsMdihFNGgc0yAgjdZlyNUa8IxUfxLw==", + "dependencies": { + "@babel/runtime": "^7.11.2", + "@mediapipe/tasks-vision": "0.10.8", + "@monogrid/gainmap-js": "^3.0.5", + "@react-spring/three": "~9.6.1", + "@use-gesture/react": "^10.2.24", + "camera-controls": "^2.4.2", + "cross-env": "^7.0.3", + "detect-gpu": "^5.0.28", + "glsl-noise": "^0.0.0", + "hls.js": "^1.5.17", + "maath": "^0.10.7", + "meshline": "^3.1.6", + "react-composer": "^5.0.3", + "stats-gl": "^2.0.0", + "stats.js": "^0.17.0", + "suspend-react": "^0.1.3", + "three-mesh-bvh": "^0.7.8", + "three-stdlib": "^2.29.9", + "troika-three-text": "^0.49.0", + "tunnel-rat": "^0.1.2", + "utility-types": "^3.10.0", + "uuid": "^9.0.1", + "zustand": "^3.7.1" + }, + "peerDependencies": { + "@react-three/fiber": ">=8.0", + "react": ">=18.0", + "react-dom": ">=18.0", + "three": ">=0.137" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/@react-three/drei/node_modules/three-mesh-bvh": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/three-mesh-bvh/-/three-mesh-bvh-0.7.8.tgz", + "integrity": "sha512-BGEZTOIC14U0XIRw3tO4jY7IjP7n7v24nv9JXS1CyeVRWOCkcOMhRnmENUjuV39gktAw4Ofhr0OvIAiTspQrrw==", + "deprecated": "Deprecated due to three.js version incompatibility. Please use v0.8.0, instead.", + "peerDependencies": { + "three": ">= 0.151.0" + } + }, + "node_modules/@react-three/drei/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@react-three/drei/node_modules/zustand": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", + "integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==", + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } + } + }, + "node_modules/@react-three/fiber": { + "version": "8.17.10", + "resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-8.17.10.tgz", + "integrity": "sha512-S6bqa4DqUooEkInYv/W+Jklv2zjSYCXAhm6qKpAQyOXhTEt5gBXnA7W6aoJ0bjmp9pAeaSj/AZUoz1HCSof/uA==", + "dependencies": { + "@babel/runtime": "^7.17.8", + "@types/debounce": "^1.2.1", + "@types/react-reconciler": "^0.26.7", + "@types/webxr": "*", + "base64-js": "^1.5.1", + "buffer": "^6.0.3", + "debounce": "^1.2.1", + "its-fine": "^1.0.6", + "react-reconciler": "^0.27.0", + "scheduler": "^0.21.0", + "suspend-react": "^0.1.3", + "zustand": "^3.7.1" + }, + "peerDependencies": { + "expo": ">=43.0", + "expo-asset": ">=8.4", + "expo-file-system": ">=11.0", + "expo-gl": ">=11.0", + "react": ">=18.0", + "react-dom": ">=18.0", + "react-native": ">=0.64", + "three": ">=0.133" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + }, + "expo-asset": { + "optional": true + }, + "expo-file-system": { + "optional": true + }, + "expo-gl": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/@react-three/fiber/node_modules/zustand": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", + "integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==", + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } + } + }, + "node_modules/@react-three/postprocessing": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/@react-three/postprocessing/-/postprocessing-2.16.3.tgz", + "integrity": "sha512-ftodXpUsy0/mzn0KqyV7MBau71dD9C5UOFnB3kHhCLNoxjKYQWZa9do0olJTSkl3owYXRfNHcLriK1Xn8wxZJw==", + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3", + "maath": "^0.6.0", + "n8ao": "^1.6.6", + "postprocessing": "^6.32.1", + "three-stdlib": "^2.23.4" + }, + "peerDependencies": { + "@react-three/fiber": ">=8.0", + "react": ">=18.0", + "three": ">= 0.138.0" + } + }, + "node_modules/@react-three/postprocessing/node_modules/maath": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/maath/-/maath-0.6.0.tgz", + "integrity": "sha512-dSb2xQuP7vDnaYqfoKzlApeRcR2xtN8/f7WV/TMAkBC8552TwTLtOO0JTcSygkYMjNDPoo6V01jTw/aPi4JrMw==", + "license": "MIT", + "peerDependencies": { + "@types/three": ">=0.144.0", + "three": ">=0.144.0" + } + }, + "node_modules/@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "dependencies": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/pluginutils/node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==" + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz", + "integrity": "sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==" + }, + "node_modules/@sinclair/typebox": { + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==" + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "license": "MIT" + }, + "node_modules/@stitches/react": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@stitches/react/-/react-1.2.8.tgz", + "integrity": "sha512-9g9dWI4gsSVe8bNLlb+lMkBYsnIKCZTmvqvDG+Avnn69XfmHZKiaMrx7cgTaddq7aTPPmXiTsbFcUy0xgI4+wA==", + "license": "MIT", + "peerDependencies": { + "react": ">= 16.3.0" + } + }, + "node_modules/@surma/rollup-plugin-off-main-thread": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", + "dependencies": { + "ejs": "^3.1.6", + "json5": "^2.2.0", + "magic-string": "^0.25.0", + "string.prototype.matchall": "^4.0.6" + } + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", + "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", + "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", + "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", + "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", + "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", + "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", + "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", + "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", + "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", + "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", + "@svgr/babel-plugin-transform-svg-component": "^5.5.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/core": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", + "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", + "dependencies": { + "@svgr/plugin-jsx": "^5.5.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", + "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", + "dependencies": { + "@babel/types": "^7.12.6" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", + "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", + "dependencies": { + "@babel/core": "^7.12.3", + "@svgr/babel-preset": "^5.5.0", + "@svgr/hast-util-to-babel-ast": "^5.5.0", + "svg-parser": "^2.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", + "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", + "dependencies": { + "cosmiconfig": "^7.0.0", + "deepmerge": "^4.2.2", + "svgo": "^1.2.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/webpack": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", + "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/plugin-transform-react-constant-elements": "^7.12.1", + "@babel/preset-env": "^7.12.1", + "@babel/preset-react": "^7.12.5", + "@svgr/core": "^5.5.0", + "@svgr/plugin-jsx": "^5.5.0", + "@svgr/plugin-svgo": "^5.5.0", + "loader-utils": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", + "integrity": "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==", + "dependencies": { + "@adobe/css-tools": "^4.0.1", + "@babel/runtime": "^7.9.2", + "@types/testing-library__jest-dom": "^5.9.1", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.5.6", + "lodash": "^4.17.15", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=8", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/react": { + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.4.0.tgz", + "integrity": "sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^8.5.0", + "@types/react-dom": "^18.0.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@testing-library/react/node_modules/@testing-library/dom": { + "version": "8.20.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz", + "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@testing-library/react/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/@testing-library/user-event": { + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", + "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "node_modules/@turf/along": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/along/-/along-7.1.0.tgz", + "integrity": "sha512-WLgBZJ/B6CcASF6WL7M+COtHlVP0hBrMbrtKyF7KBlicwRuijJZXDtEQA5oLgr+k1b2HqGN+UqH2A0/E719enQ==", + "dependencies": { + "@turf/bearing": "^7.1.0", + "@turf/destination": "^7.1.0", + "@turf/distance": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/angle": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/angle/-/angle-7.1.0.tgz", + "integrity": "sha512-YMHEV/YrARsWgWoQuXEWrQMsvB8z67nTMw2eiLZ883V7jwkhWQGvCW6W+/mGgsWQdHppjCZNcKryryhD2GRWVA==", + "dependencies": { + "@turf/bearing": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/rhumb-bearing": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/area": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/area/-/area-7.1.0.tgz", + "integrity": "sha512-w91FEe02/mQfMPRX2pXua48scFuKJ2dSVMF2XmJ6+BJfFiCPxp95I3+Org8+ZsYv93CDNKbf0oLNEPnuQdgs2g==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/bbox": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/bbox/-/bbox-7.1.0.tgz", + "integrity": "sha512-PdWPz9tW86PD78vSZj2fiRaB8JhUHy6piSa/QXb83lucxPK+HTAdzlDQMTKj5okRCU8Ox/25IR2ep9T8NdopRA==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/bbox-clip": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/bbox-clip/-/bbox-clip-7.1.0.tgz", + "integrity": "sha512-PhZubKCzF/afwStUzODqOJluiCbCw244lCtVhXA9F+Pgkhvk8KvbFdgpPquOZ45OwuktrchSB28BrBkSBiadHw==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/bbox-polygon": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/bbox-polygon/-/bbox-polygon-7.1.0.tgz", + "integrity": "sha512-fvZB09ErCZOVlWVDop836hmpKaGUmfXnR9naMhS73A/8nn4M3hELbQtMv2R8gXj7UakXCuxS/i9erdpDFZ2O+g==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/bearing": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/bearing/-/bearing-7.1.0.tgz", + "integrity": "sha512-X5lackrZ6FW+YhgjWxwVFRgWD1j4xm4t5VvE6EE6v/1PVaHQ5OCjf6u1oaLx5LSG+gaHUhjTlAHrn9MYPFaeTA==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/bezier-spline": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/bezier-spline/-/bezier-spline-7.1.0.tgz", + "integrity": "sha512-bhBY70bcVYJEosuW7B/TFtnE5rmPTTpxmJvljhGC0eyM84oNVv7apDBuseb5KdlTOOBIvdD9nIE4qV8lmplp6w==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-clockwise": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/boolean-clockwise/-/boolean-clockwise-7.1.0.tgz", + "integrity": "sha512-H5DYno+gHwZx+VaiC8DUBZXZQlxYecdSvqCfCACWi1uMsKvlht/O+xy65hz2P57lk2smlcV+1ETFVxJlEZduYg==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-concave": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/boolean-concave/-/boolean-concave-7.1.0.tgz", + "integrity": "sha512-IFCN25DI+hvngxIsv4+MPuRJQRl/Lz/xnZgpH82leCn4Jqn5wW7KqKFMz7G4GoKK+93cK5/6ioAxY7hVWBXxJw==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-contains": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/boolean-contains/-/boolean-contains-7.1.0.tgz", + "integrity": "sha512-ldy4j1/RVChYTYjEb4wWaE/JyF1jA87WpsB4eVLic6OcAYJGs7POF1kfKbcdkJJiRBmhI3CXNA+u+m9y4Z/j3g==", + "dependencies": { + "@turf/bbox": "^7.1.0", + "@turf/boolean-point-in-polygon": "^7.1.0", + "@turf/boolean-point-on-line": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-crosses": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/boolean-crosses/-/boolean-crosses-7.1.0.tgz", + "integrity": "sha512-LK8UM3AENycuGinLCDaL0QSznGMnD0XsjFDGnY4KehshiL5Zd8ZsPyKmHOPygUJT9DWeH69iLx459lOc+5Vj2w==", + "dependencies": { + "@turf/boolean-point-in-polygon": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/line-intersect": "^7.1.0", + "@turf/polygon-to-line": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-disjoint": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/boolean-disjoint/-/boolean-disjoint-7.1.0.tgz", + "integrity": "sha512-JapOG03kOCoGeYMWgTQjEifhr1nUoK4Os2cX0iC5X9kvZF4qCHeruX8/rffBQDx7PDKQKusSTXq8B1ISFi0hOw==", + "dependencies": { + "@turf/boolean-point-in-polygon": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/line-intersect": "^7.1.0", + "@turf/meta": "^7.1.0", + "@turf/polygon-to-line": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-equal": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/boolean-equal/-/boolean-equal-7.1.0.tgz", + "integrity": "sha512-deghtFMApc7fNsdXtZdgYR4gsU+TVfowcv666nrvZbPPsXL6NTYGBhDFmYXsJ8gPTCGT9uT0WXppdgT8diWOxA==", + "dependencies": { + "@turf/clean-coords": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "geojson-equality-ts": "^1.0.2", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-intersects": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/boolean-intersects/-/boolean-intersects-7.1.0.tgz", + "integrity": "sha512-gpksWbb0RT+Z3nfqRfoACY3KEFyv2BPaxJ3L76PH67DhHZviq3Nfg85KYbpuhS64FSm+9tXe4IaKn6EjbHo20g==", + "dependencies": { + "@turf/boolean-disjoint": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-overlap": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/boolean-overlap/-/boolean-overlap-7.1.0.tgz", + "integrity": "sha512-mJRN0X8JiPm8eDZk5sLvIrsP03A2GId6ijx4VgSE1AvHwV6qB561KlUbWxga2AScocIfv/y/qd2OCs+/TQSZcg==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/line-intersect": "^7.1.0", + "@turf/line-overlap": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "geojson-equality-ts": "^1.0.2", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-parallel": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/boolean-parallel/-/boolean-parallel-7.1.0.tgz", + "integrity": "sha512-tA84Oux0X91CxUc6c/lZph5W9wUZGNT4fxFOg5Gp1IMTSwtxSYL1LMvKsr/VmMnwdOUkNcqAgU06+t4wBLtDfg==", + "dependencies": { + "@turf/clean-coords": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/line-segment": "^7.1.0", + "@turf/rhumb-bearing": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-point-in-polygon": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/boolean-point-in-polygon/-/boolean-point-in-polygon-7.1.0.tgz", + "integrity": "sha512-mprVsyIQ+ijWTZwbnO4Jhxu94ZW2M2CheqLiRTsGJy0Ooay9v6Av5/Nl3/Gst7ZVXxPqMeMaFYkSzcTc87AKew==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "point-in-polygon-hao": "^1.1.0", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-point-on-line": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/boolean-point-on-line/-/boolean-point-on-line-7.1.0.tgz", + "integrity": "sha512-Kd83EjeTyY4kVMAhcW3Lb8aChwh24BUIhmpE9Or8M+ETNsFGzn9M7qtIySJHLRzKAL3letvWSKXKQPuK1AhAzg==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-touches": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/boolean-touches/-/boolean-touches-7.1.0.tgz", + "integrity": "sha512-qN4LCs3RfVtNAAdn5GpsUFBqoZyAaK9UzSnGSh67GP9sy5M8MEHwM/HAJ5zGWJqQADrczI3U6BRWGLcGfGSz3Q==", + "dependencies": { + "@turf/boolean-point-in-polygon": "^7.1.0", + "@turf/boolean-point-on-line": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-valid": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/boolean-valid/-/boolean-valid-7.1.0.tgz", + "integrity": "sha512-zq1QCfQEyn+piHlvxxDifjmsJn2xl53i4mnKFYdMQI/i09XiX+Fi/MVM3i2hf3D5AsEPsud8Tk7C7rWNCm4nVw==", + "dependencies": { + "@turf/bbox": "^7.1.0", + "@turf/boolean-crosses": "^7.1.0", + "@turf/boolean-disjoint": "^7.1.0", + "@turf/boolean-overlap": "^7.1.0", + "@turf/boolean-point-in-polygon": "^7.1.0", + "@turf/boolean-point-on-line": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/line-intersect": "^7.1.0", + "@types/geojson": "^7946.0.10", + "geojson-polygon-self-intersections": "^1.2.1", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-within": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/boolean-within/-/boolean-within-7.1.0.tgz", + "integrity": "sha512-pgXgKCzYHssADQ1nClB1Q9aWI/dE1elm2jy3B5X59XdoFXKrKDZA+gCHYOYgp2NGO/txzVfl3UKvnxIj54Fa4w==", + "dependencies": { + "@turf/bbox": "^7.1.0", + "@turf/boolean-point-in-polygon": "^7.1.0", + "@turf/boolean-point-on-line": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/buffer": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/buffer/-/buffer-7.1.0.tgz", + "integrity": "sha512-QM3JiCMYA19k5ouO8wJtvICX3Y8XntxVpDfHSKhFFidZcCkMTR2PWWOpwS6EoL3t75rSKw/FOLIPLZGtIu963w==", + "dependencies": { + "@turf/bbox": "^7.1.0", + "@turf/center": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/jsts": "^2.7.1", + "@turf/meta": "^7.1.0", + "@turf/projection": "^7.1.0", + "@types/geojson": "^7946.0.10", + "d3-geo": "1.7.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/center": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/center/-/center-7.1.0.tgz", + "integrity": "sha512-p9AvBMwNZmRg65kU27cGKHAUQnEcdz8Y7f/i5DvaMfm4e8zmawr+hzPKXaUpUfiTyLs8Xt2W9vlOmNGyH+6X3w==", + "dependencies": { + "@turf/bbox": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/center-mean": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/center-mean/-/center-mean-7.1.0.tgz", + "integrity": "sha512-NQZB1LUVsyAD+p0+D4huzX2XVnfVx1yEEI9EX602THmi+g+nkge4SK9OMV11ov/Tv8JJ6aVNVPo/cy1vm/LCIQ==", + "dependencies": { + "@turf/bbox": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/center-median": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/center-median/-/center-median-7.1.0.tgz", + "integrity": "sha512-jx4/Ql5+v41Cd0J/gseNCUbLTzWUT2LUaiXn8eFWDrvmEgqHIx7KJcGcJd5HzV+9zJwng4AXxyh5NMvUR0NjwA==", + "dependencies": { + "@turf/center-mean": "^7.1.0", + "@turf/centroid": "^7.1.0", + "@turf/distance": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/center-of-mass": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/center-of-mass/-/center-of-mass-7.1.0.tgz", + "integrity": "sha512-j38oBlj7LBoCjZbrIo8EoHVGhk7UQmMLQ1fe8ZPAF9pd05XEL1qxyHKZKdQ/deGISiaEhXCyfLNrKAHAuy25RA==", + "dependencies": { + "@turf/centroid": "^7.1.0", + "@turf/convex": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/centroid": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/centroid/-/centroid-7.1.0.tgz", + "integrity": "sha512-1Y1b2l+ZB1CZ+ITjUCsGqC4/tSjwm/R4OUfDztVqyyCq/VvezkLmTNqvXTGXgfP0GXkpv68iCfxF5M7QdM5pJQ==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/circle": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/circle/-/circle-7.1.0.tgz", + "integrity": "sha512-6qhF1drjwH0Dg3ZB9om1JkWTJfAqBcbtIrAj5UPlrAeHP87hGoCO2ZEsFEAL9Q18vntpivT89Uho/nqQUjJhYw==", + "dependencies": { + "@turf/destination": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/clean-coords": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/clean-coords/-/clean-coords-7.1.0.tgz", + "integrity": "sha512-q1U8UbRVL5cRdwOlNjD8mad8pWjFGe0s4ihg1pSiVNq7i47WASJ3k20yZiUFvuAkyNjV0rZ/A7Jd7WzjcierFg==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/clone": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/clone/-/clone-7.1.0.tgz", + "integrity": "sha512-5R9qeWvL7FDdBIbEemd0eCzOStr09oburDvJ1hRiPCFX6rPgzcZBQ0gDmZzoF4AFcNLb5IwknbLZjVLaUGWtFA==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/clusters": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/clusters/-/clusters-7.1.0.tgz", + "integrity": "sha512-7CY3Ai+5V6q2O9/IgqLpJQrmrTy7aUJjTW1iRan8Tz3WixvxyJHeS3iyRy8Oc0046chQIaHLtyTgKVt2QdsPSA==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/clusters-dbscan": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/clusters-dbscan/-/clusters-dbscan-7.1.0.tgz", + "integrity": "sha512-BmrBTOEaKN5FIED6b3yb3V3ejfK0A2Q3pT9/ji3mcRLJiBaRGeiN5V6gtGXe7PeMYdoqhHykU5Ye2uUtREWRdQ==", + "dependencies": { + "@turf/clone": "^7.1.0", + "@turf/distance": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "rbush": "^3.0.1", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/clusters-kmeans": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/clusters-kmeans/-/clusters-kmeans-7.1.0.tgz", + "integrity": "sha512-M8cCqR6iE1jDSUF/UU9QdPUFrobZS2fo59TfF1IRHZ2G1EjbcK4GzZcUfmQS6DZraGudYutpMYIuNdm1dPMqdQ==", + "dependencies": { + "@turf/clone": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "skmeans": "0.9.7", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/collect": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/collect/-/collect-7.1.0.tgz", + "integrity": "sha512-6indMWLiKeBh4AsioNeFeFnO0k9U5CBsWAFEje6tOEFI4c+P7LF9mNA9z91H8KkrhegR9XNO5Vm2rmdY63aYXw==", + "dependencies": { + "@turf/bbox": "^7.1.0", + "@turf/boolean-point-in-polygon": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@types/geojson": "^7946.0.10", + "rbush": "^3.0.1", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/combine": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/combine/-/combine-7.1.0.tgz", + "integrity": "sha512-Xl7bGKKjgzIq2T/IemS6qnIykyuxU6cMxKtz+qLeWJGoNww/BllwxXePSV+dWRPXZTFFj96KIhBXAW0aUjAQKQ==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/concave": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/concave/-/concave-7.1.0.tgz", + "integrity": "sha512-aSid53gYRee4Tjc4pfeI3KI+RoBUnL/hRMilxIPduagTgZZS+cvvk01OQWBKm5UTVfHRGuy0XIqnK8y9RFinDQ==", + "dependencies": { + "@turf/clone": "^7.1.0", + "@turf/distance": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/meta": "^7.1.0", + "@turf/tin": "^7.1.0", + "@types/geojson": "^7946.0.10", + "topojson-client": "3.x", + "topojson-server": "3.x", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/convex": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/convex/-/convex-7.1.0.tgz", + "integrity": "sha512-w9fUMZYE36bLrEWEj7L7aVMCB7NBtr2o8G+avRvUIwF4DPqbtcjlcZE9EEBfq44uYdn+/Pke6Iq42T/zyD/cpg==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "concaveman": "^1.2.1", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/destination": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/destination/-/destination-7.1.0.tgz", + "integrity": "sha512-97XuvB0iaAiMg86hrnZ529WwP44TQAA9mmI5PMlchACiA4LFrEtWjjDzvO6234coieoqhrw6dZYcJvd5O2PwrQ==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/difference": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/difference/-/difference-7.1.0.tgz", + "integrity": "sha512-+JVzdskICQ8ULKQ9CpWUM5kBvoXxN4CO78Ez/Ki3/7NXl7+HM/nb12B0OyM8hkJchpb8TsOi0YwyJiKMqEpTBA==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "polygon-clipping": "^0.15.3", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/dissolve": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/dissolve/-/dissolve-7.1.0.tgz", + "integrity": "sha512-fyOnCSYVUZ8SF9kt9ROnQYlkJTE0hpWSoWwbMZQCAR7oVZVPiuPq7eIbzTP+k5jzEAnofsqoGs5qVDTjHcWMiw==", + "dependencies": { + "@turf/flatten": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "polygon-clipping": "^0.15.3", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/distance": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/distance/-/distance-7.1.0.tgz", + "integrity": "sha512-hhNHhxCHB3ddzAGCNY4BtE29OZh+DAJPvUapQz+wOjISnlwvMcwLKvslgHWSYF536QDVe/93FEU2q67+CsZTPA==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/distance-weight": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/distance-weight/-/distance-weight-7.1.0.tgz", + "integrity": "sha512-8m6s4y8Yyt6r3itf44yAJjXC+62UkrkhOpskIfaE0lHcBcvZz9wjboHoBf3bS4l/42E4StcanbFZdjOpODAdZw==", + "dependencies": { + "@turf/centroid": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/ellipse": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/ellipse/-/ellipse-7.1.0.tgz", + "integrity": "sha512-AfOahUmStDExWGPg8ZWxxkgom+fdJs7Mn9DzZH+fV/uZ+je1bLQpbPCUu9/ev6u/HhbYGl4VAL/CeQzjOyy6LQ==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/rhumb-destination": "^7.1.0", + "@turf/transform-rotate": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/envelope": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/envelope/-/envelope-7.1.0.tgz", + "integrity": "sha512-WeLQse9wuxsxhzSqrJA6Ha7rLWnLKgdKY9cfxmJKHSpgqcJyNk60m7+T3UpI/nkGwpfbpeyB3EGC1EWPbxiDUg==", + "dependencies": { + "@turf/bbox": "^7.1.0", + "@turf/bbox-polygon": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/explode": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/explode/-/explode-7.1.0.tgz", + "integrity": "sha512-To+GUbU6HtcHZ8S0w/dw1EbdQIOCXALTr6Ug5/IFg8hIBMJelDpVr3Smwy8uqhDRFinY2eprBwQnDPcd10eCqA==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/flatten": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/flatten/-/flatten-7.1.0.tgz", + "integrity": "sha512-Kb23pqEarcLsdBqnQcK0qTrSMiWNTVb9tOFrNlZc66DIhDLAdpOKG4eqk00CMoUzWTixlnawDgJRqcStRrR4WA==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/flip": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/flip/-/flip-7.1.0.tgz", + "integrity": "sha512-vac73W8WblzzNFanzWYLBzWDIcqc5xczOrtEO07RDEiKEI3Heo0471Jed3v9W506uuOX6/HAiCjXbRjTLjiLfw==", + "dependencies": { + "@turf/clone": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/geojson-rbush": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/geojson-rbush/-/geojson-rbush-7.1.0.tgz", + "integrity": "sha512-j1C7Ohlxa1z644bNOpgibcFGaDLgLXGLOzwF1tfQaP5y7E4PJQUXL0DWIgNb3Ke7gZC05LPHM25a5TRReUfFBQ==", + "dependencies": { + "@turf/bbox": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "rbush": "^3.0.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/great-circle": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/great-circle/-/great-circle-7.1.0.tgz", + "integrity": "sha512-92q5fqUp5oW+FYekUIrUVR5PZBWbOV6NHKHPIiNahiPvtkpZItbbjoO+tGn5+2i8mxZP9FGOthayJe4V0a1xkg==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/helpers": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-7.1.0.tgz", + "integrity": "sha512-dTeILEUVeNbaEeoZUOhxH5auv7WWlOShbx7QSd4s0T4Z0/iz90z9yaVCtZOLbU89umKotwKaJQltBNO9CzVgaQ==", + "dependencies": { + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/hex-grid": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/hex-grid/-/hex-grid-7.1.0.tgz", + "integrity": "sha512-I+Apx0smOPkMzaS5HHL44YOxSkSUvrz+wtSIETsDFWWLT2xKNkaaEcYU5MkgSoEfQsj082M7EkOIIpocXlA3kg==", + "dependencies": { + "@turf/distance": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/intersect": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/interpolate": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/interpolate/-/interpolate-7.1.0.tgz", + "integrity": "sha512-VWec1OW9gHZLPS3yYkUXAHKMGQuYO4aqh8WCltT7Ym4efrKqkSOE5T+mBqO68QgcL8nY4kiNa8lxwXd0SfXDSA==", + "dependencies": { + "@turf/bbox": "^7.1.0", + "@turf/centroid": "^7.1.0", + "@turf/clone": "^7.1.0", + "@turf/distance": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/hex-grid": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/meta": "^7.1.0", + "@turf/point-grid": "^7.1.0", + "@turf/square-grid": "^7.1.0", + "@turf/triangle-grid": "^7.1.0", + "@types/geojson": "^7946.0.10" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/intersect": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/intersect/-/intersect-7.1.0.tgz", + "integrity": "sha512-T0VhI6yhptX9EoMsuuBETyqV+edyq31SUC8bfuM6kdJ5WwJ0EvUfQoC+3bhMtCOn60lHawrUuGBgW+vCO8KGMg==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "polygon-clipping": "^0.15.3", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/invariant": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-7.1.0.tgz", + "integrity": "sha512-OCLNqkItBYIP1nE9lJGuIUatWGtQ4rhBKAyTfFu0z8npVzGEYzvguEeof8/6LkKmTTEHW53tCjoEhSSzdRh08Q==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/isobands": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/isobands/-/isobands-7.1.0.tgz", + "integrity": "sha512-iMLTOP/K5C05AttF4N1WeV+KrY4O5VWW/abO0N86XCWh1OeqmIUgqIBKEmhDzttAqC0UK2YrUfj0lI1Ez1fYZQ==", + "dependencies": { + "@turf/area": "^7.1.0", + "@turf/bbox": "^7.1.0", + "@turf/boolean-point-in-polygon": "^7.1.0", + "@turf/explode": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "marchingsquares": "^1.3.3", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/isolines": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/isolines/-/isolines-7.1.0.tgz", + "integrity": "sha512-V6QTHXBT5ZsL3s9ZVBJgHYtz3gCFKqNnQLysNE02LE0fVVqaSao3sFrcpghmdDxf0hBCDK8lZVvyRGO6o32LHQ==", + "dependencies": { + "@turf/bbox": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "marchingsquares": "^1.3.3", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/jsts": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@turf/jsts/-/jsts-2.7.1.tgz", + "integrity": "sha512-+nwOKme/aUprsxnLSfr2LylV6eL6T1Tuln+4Hl92uwZ8FrmjDRCH5Bi1LJNVfWCiYgk8+5K+t2zDphWNTsIFDA==", + "dependencies": { + "jsts": "2.7.1" + } + }, + "node_modules/@turf/kinks": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/kinks/-/kinks-7.1.0.tgz", + "integrity": "sha512-KKLYUsyJPU17fODwA81mhHzFYGQYocdbk9NxDPCcdRHvxzM8t95lptkGx/2k/9rXBs1DK7NmyzI4m7zDO0DK7g==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/length": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/length/-/length-7.1.0.tgz", + "integrity": "sha512-wUJj9WLKEudG1ngNao2ZwD+Dt6UkvWIbubuJ6lR6FndFDL3iezFhNGy0IXS+0xH9kXi2apiTnM9Vk5+i8BTEvQ==", + "dependencies": { + "@turf/distance": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/line-arc": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/line-arc/-/line-arc-7.1.0.tgz", + "integrity": "sha512-9/bM34PozTyJ5FXXPAzl/j0RpcTImgMFJZ0WhH0pZZEZRum6P0rJnENt2E2qI441zeozQ9H6X5DCiJogDmRUEw==", + "dependencies": { + "@turf/circle": "^7.1.0", + "@turf/destination": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/line-chunk": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/line-chunk/-/line-chunk-7.1.0.tgz", + "integrity": "sha512-1lIUfqAQvCWAuUNC2ip8UYmM5kDltXOidLPW45Ee1OAIKYGBeFNtjwnxc0mQ40tnfTXclTYLDdOOP9LShspT9w==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/length": "^7.1.0", + "@turf/line-slice-along": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/line-intersect": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/line-intersect/-/line-intersect-7.1.0.tgz", + "integrity": "sha512-JI3dvOsAoCqd4vUJ134FIzgcC42QpC/tBs+b4OJoxWmwDek3REv4qGaZY6wCg9X4hFSlCKFcnhMIQQZ/n720Qg==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@types/geojson": "^7946.0.10", + "sweepline-intersections": "^1.5.0", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/line-offset": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/line-offset/-/line-offset-7.1.0.tgz", + "integrity": "sha512-pz6irzhiQlJurU7DoXada6k3ei7PzY+VpsE/Wotm0D2KEAnoxqum2WK0rqqrhKPHKn+xpUGsHN9W/6K+qtmaHg==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/line-overlap": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/line-overlap/-/line-overlap-7.1.0.tgz", + "integrity": "sha512-BdHuEoFAtqvVw3LkjCdivG035nfuwZuxji2ijst+mkmDnlv7uwSBudJqcDGjU6up2r8P1mXChS4im4xjUz+lwg==", + "dependencies": { + "@turf/boolean-point-on-line": "^7.1.0", + "@turf/geojson-rbush": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/line-segment": "^7.1.0", + "@turf/meta": "^7.1.0", + "@turf/nearest-point-on-line": "^7.1.0", + "@types/geojson": "^7946.0.10", + "fast-deep-equal": "^3.1.3", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/line-segment": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/line-segment/-/line-segment-7.1.0.tgz", + "integrity": "sha512-9rgIIH6ZzC3IiWxDQtKsq+j6eu8fRinMkJeusfI9HqOTm4vO02Ll4F/FigjOMOO/6X3TJ+Pqe3gS99TUaBINkw==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/line-slice": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/line-slice/-/line-slice-7.1.0.tgz", + "integrity": "sha512-44xcjgMQxTa7tTAZlSD3t1cFjHi5SCfAqjg1ONv45EYKsQSonPaxD7LGzCbU5pR2RJjx3R7QRJx2G88hnGcXjQ==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/nearest-point-on-line": "^7.1.0", + "@types/geojson": "^7946.0.10" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/line-slice-along": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/line-slice-along/-/line-slice-along-7.1.0.tgz", + "integrity": "sha512-UwfnFORZnu4xdnuRXiQM3ODa8f9Q0FBjQF/XHNsPEI/xxmnwgQj3MZiULbAeHUbtU/7psTC7gEjfE3Lf0tcKQw==", + "dependencies": { + "@turf/bearing": "^7.1.0", + "@turf/destination": "^7.1.0", + "@turf/distance": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@types/geojson": "^7946.0.10" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/line-split": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/line-split/-/line-split-7.1.0.tgz", + "integrity": "sha512-QqUAmtlrnEu75cpLOmpEuiYU63BeVwpSKOBllBbu5gkP+7H/WBM/9fh7J0VgHNFHzqZCKiu8v4158k+CZr0QAg==", + "dependencies": { + "@turf/bbox": "^7.1.0", + "@turf/geojson-rbush": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/line-intersect": "^7.1.0", + "@turf/line-segment": "^7.1.0", + "@turf/meta": "^7.1.0", + "@turf/nearest-point-on-line": "^7.1.0", + "@turf/square": "^7.1.0", + "@turf/truncate": "^7.1.0", + "@types/geojson": "^7946.0.10" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/line-to-polygon": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/line-to-polygon/-/line-to-polygon-7.1.0.tgz", + "integrity": "sha512-n/IWBRbo+l4XDTz4sfQsQm5bU9xex8KrthK397jQasd7a9PiOKGon9Z1t/lddTJhND6ajVyJ3hl+eZMtpQaghQ==", + "dependencies": { + "@turf/bbox": "^7.1.0", + "@turf/clone": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/mask": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/mask/-/mask-7.1.0.tgz", + "integrity": "sha512-d+u3IIiRhe17TDfP/+UMn9qRlJYPJpK7sj6WorsssluGi0yIG/Z24uWpcLskWKSI8NNgkIbDrp+GIYkJi2t7SA==", + "dependencies": { + "@turf/clone": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@types/geojson": "^7946.0.10", + "polygon-clipping": "^0.15.3", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/meta": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/meta/-/meta-7.1.0.tgz", + "integrity": "sha512-ZgGpWWiKz797Fe8lfRj7HKCkGR+nSJ/5aKXMyofCvLSc2PuYJs/qyyifDPWjASQQCzseJ7AlF2Pc/XQ/3XkkuA==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@types/geojson": "^7946.0.10" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/midpoint": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/midpoint/-/midpoint-7.1.0.tgz", + "integrity": "sha512-uiUU9TwRZOCeiTUn8+7oE6MJUvclfq+n6KQ5VCMTZXiRUJjPu7nDLpBle1t2WSv7/w7O0kSQ4FfKXh0gHnkJOw==", + "dependencies": { + "@turf/bearing": "^7.1.0", + "@turf/destination": "^7.1.0", + "@turf/distance": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/moran-index": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/moran-index/-/moran-index-7.1.0.tgz", + "integrity": "sha512-xsvAr3IRF/C6PlRMoN/ANrRx6c3QFUJgBCIVfI7re+Lkdprrzgw1HZA48ZjP4F91xbhgA1scnRgQdHFi2vO2SA==", + "dependencies": { + "@turf/distance-weight": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/nearest-neighbor-analysis": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/nearest-neighbor-analysis/-/nearest-neighbor-analysis-7.1.0.tgz", + "integrity": "sha512-FAhT8/op3DuvqH0XFhv055JhYq/FC4aaIxEZ4hj8c7W6sYhUHAQgdRZ0tJ1RLe5/h+eXhCTbQ+DFfnfv3klu8g==", + "dependencies": { + "@turf/area": "^7.1.0", + "@turf/bbox": "^7.1.0", + "@turf/bbox-polygon": "^7.1.0", + "@turf/centroid": "^7.1.0", + "@turf/distance": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@turf/nearest-point": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/nearest-point": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/nearest-point/-/nearest-point-7.1.0.tgz", + "integrity": "sha512-VyInmhqfVWp+jE7sCK95o46qc4tDjAgzbRfRjr+rTgfFS1Sndyy1PdwyNn6TjBFDxiM6e+mjMEeGPjb1smJlEg==", + "dependencies": { + "@turf/clone": "^7.1.0", + "@turf/distance": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/nearest-point-on-line": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/nearest-point-on-line/-/nearest-point-on-line-7.1.0.tgz", + "integrity": "sha512-aTjAOm7ab0tl5JoxGYRx/J/IbRL1DY1ZCIYQDMEQjK5gOllhclgeBC0wDXDkEZFGaVftjw0W2RtE2I0jX7RG4A==", + "dependencies": { + "@turf/bearing": "^7.1.0", + "@turf/destination": "^7.1.0", + "@turf/distance": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/line-intersect": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/nearest-point-to-line": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/nearest-point-to-line/-/nearest-point-to-line-7.1.0.tgz", + "integrity": "sha512-rY2F/iY4S6U8H0hIoOI25xMWYEiKywxeTvTvn5GP8KCu+2oemfZROWa7n2+hQDRwO2/uaegrGEpxO7zlFarvzg==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/meta": "^7.1.0", + "@turf/point-to-line-distance": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/planepoint": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/planepoint/-/planepoint-7.1.0.tgz", + "integrity": "sha512-hFORBkCd7Q0kNUzLqksT4XglLgTQF9tCjG+dbnZ1VehpZu+w+vlHdoW/mY7XCX3Kj1ObiyzVmXffmVYgwXwF6Q==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/point-grid": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/point-grid/-/point-grid-7.1.0.tgz", + "integrity": "sha512-ihuuUcWuCu4Z1+34UYCM5NGsU2DJaB4uE8cS3jDQoUqlc+8ii2ng8kcGEtTwVn0HdPsoKA7bgvSZcisJO0v6Ww==", + "dependencies": { + "@turf/boolean-within": "^7.1.0", + "@turf/distance": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/point-on-feature": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/point-on-feature/-/point-on-feature-7.1.0.tgz", + "integrity": "sha512-lOO5J9I0diuGbN+r6jViEKRH3qfymsBvv25b7U0MuP8g/YC19ncUXZ86dmKfJx1++Rb485DS9h0nFvPmJpaOdg==", + "dependencies": { + "@turf/boolean-point-in-polygon": "^7.1.0", + "@turf/center": "^7.1.0", + "@turf/explode": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/nearest-point": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/point-to-line-distance": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/point-to-line-distance/-/point-to-line-distance-7.1.0.tgz", + "integrity": "sha512-Ps9eTOCaiNgxDaSNQux0wAcSLcrI0y0zYFaD9HnVm+yCMRliQXneFti2XXotS+gR7TpgnLRAAzyx4VzJMSN2tw==", + "dependencies": { + "@turf/bearing": "^7.1.0", + "@turf/distance": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/meta": "^7.1.0", + "@turf/projection": "^7.1.0", + "@turf/rhumb-bearing": "^7.1.0", + "@turf/rhumb-distance": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/points-within-polygon": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/points-within-polygon/-/points-within-polygon-7.1.0.tgz", + "integrity": "sha512-SzqeD9Gcp11rEya+rCVMy6IPuYMrphNEkCiQ39W6ec9hsaqKlruqmtudKhhckMGVLVUUBCQAu5f55yjcDfVW2w==", + "dependencies": { + "@turf/boolean-point-in-polygon": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/polygon-smooth": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/polygon-smooth/-/polygon-smooth-7.1.0.tgz", + "integrity": "sha512-mTlmg4XUP5rKgCP/73N91owkAXIc3t1ZKLuwsJGQM1/Op48T3rJmDwVR/WZIMnVlxl5tFbssWCCB3blj4ivx9g==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/polygon-tangents": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/polygon-tangents/-/polygon-tangents-7.1.0.tgz", + "integrity": "sha512-ffBgHXtkrpgkNs8E6s9sVLSKG4lPGH3WBk294FNKBt9NS+rbhNCv8yTuOMeP0bOm/WizaCq/SUtVryJpUSoI/g==", + "dependencies": { + "@turf/bbox": "^7.1.0", + "@turf/boolean-within": "^7.1.0", + "@turf/explode": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/nearest-point": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/polygon-to-line": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/polygon-to-line/-/polygon-to-line-7.1.0.tgz", + "integrity": "sha512-FBlfyBWNQZCTVGqlJH7LR2VXmvj8AydxrA8zegqek/5oPGtQDeUgIppKmvmuNClqbglhv59QtCUVaDK4bOuCTA==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/polygonize": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/polygonize/-/polygonize-7.1.0.tgz", + "integrity": "sha512-FBjxnOzO29MbE7MWnMPHHYtOo93cQopT5pXhkuPyoKgcTUCntR1+iVFpl5YFbMkYup0j5Oexjo/pbY38lVSZGw==", + "dependencies": { + "@turf/boolean-point-in-polygon": "^7.1.0", + "@turf/envelope": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/projection": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/projection/-/projection-7.1.0.tgz", + "integrity": "sha512-3wHluMoOvXnTe7dfi0kcluTyLNG5MwGsSsK5OA98vkkLH6a1xvItn8e9GcesuT07oB2km/bgefxYEIvjQG5JCA==", + "dependencies": { + "@turf/clone": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/quadrat-analysis": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/quadrat-analysis/-/quadrat-analysis-7.1.0.tgz", + "integrity": "sha512-4O5h9PyWgpqYXja9O+kzr+qk5MUz0IkJqPtt5oWWX5s4jRcLNqiEUf+zi/GDBQkVV8jH3S5klT5CLrF1fxK3hQ==", + "dependencies": { + "@turf/area": "^7.1.0", + "@turf/bbox": "^7.1.0", + "@turf/bbox-polygon": "^7.1.0", + "@turf/centroid": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/point-grid": "^7.1.0", + "@turf/random": "^7.1.0", + "@turf/square-grid": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/random": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/random/-/random-7.1.0.tgz", + "integrity": "sha512-22mXv8ejDMUWkz8DSMMqdZb0s7a0ISJzXt6T9cHovfT//vsotzkVH+5PDxJQjvmigKMnpaUgobHmQss23tAwEQ==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/rectangle-grid": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/rectangle-grid/-/rectangle-grid-7.1.0.tgz", + "integrity": "sha512-4d2AuDj4LfMMJxNHbds5yX1oFR3mIVAB5D7mx6pFB0e+YkQW0mE2dUWhDTFGJZM+n45yqbNQ5hg19bmiXv94ug==", + "dependencies": { + "@turf/boolean-intersects": "^7.1.0", + "@turf/distance": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/rewind": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/rewind/-/rewind-7.1.0.tgz", + "integrity": "sha512-zX0KDZpeiH89m1vYLTEJdDL6mFyoAsCxcG0P94mXO7/JXWf0AaxzA9MkNnA/d2QYX0G4ioCMjZ5cD6nXb8SXzw==", + "dependencies": { + "@turf/boolean-clockwise": "^7.1.0", + "@turf/clone": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/rhumb-bearing": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/rhumb-bearing/-/rhumb-bearing-7.1.0.tgz", + "integrity": "sha512-ESZt70eOljHVnQMFKIdiu8LIHuQlpZgzh2nqSfV40BrYjsjI/sBKeK+sp2cBWk88nsSDlriPuMTNh4f50Jqpkw==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/rhumb-destination": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/rhumb-destination/-/rhumb-destination-7.1.0.tgz", + "integrity": "sha512-WA2TeO3qrv5ZrzNihtTLLYu8X4kd12WEC6JKElm99XhgLao1/4ao2SJUi43l88HqwbrnNiq4TueGQ6tYpXGU7A==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/rhumb-distance": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/rhumb-distance/-/rhumb-distance-7.1.0.tgz", + "integrity": "sha512-fR1V+yC4E1tnbdThomosiLcv0PQOwbfLSPM8rSWuxbMcJtffsncWxyJ0+N1F5juuHbcdaYhlduX8ri5I0ZCejw==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/sample": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/sample/-/sample-7.1.0.tgz", + "integrity": "sha512-9Iq/Ankr4+sgBoh4FpuVVvoW+AA10eej3FS89Zu79SFdCqUIdT7T42Nn3MlSVj4jMyA1oXyT2HIAlNWkwgLw6Q==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/sector": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/sector/-/sector-7.1.0.tgz", + "integrity": "sha512-2FI2rg//eXpa/l+WJtFfvHaf1NJ7ie2MoJ+RH5dKANtrfoof1Ed+y9dXSyuhem2tp/Srq2GhrjaSofFN5/g5vA==", + "dependencies": { + "@turf/circle": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/line-arc": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/shortest-path": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/shortest-path/-/shortest-path-7.1.0.tgz", + "integrity": "sha512-1UmFhS5zHNacLv5rszoFOXq02BGov1oJvjlDatXsSWAd+Z7tqxpDc8D+41edrXy0ZB0Yxsy6WPNagM6hG9PRaA==", + "dependencies": { + "@turf/bbox": "^7.1.0", + "@turf/bbox-polygon": "^7.1.0", + "@turf/boolean-point-in-polygon": "^7.1.0", + "@turf/clean-coords": "^7.1.0", + "@turf/distance": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/meta": "^7.1.0", + "@turf/transform-scale": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/simplify": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/simplify/-/simplify-7.1.0.tgz", + "integrity": "sha512-JypymaoiSiFzGHwEoUkK0OPW1KQSnH3hEsEW3UIRS+apzltJ4HdFovYjsfqQgGZJZ+NJ9+dv7h8pgGLYuqcBUQ==", + "dependencies": { + "@turf/clean-coords": "^7.1.0", + "@turf/clone": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/square": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/square/-/square-7.1.0.tgz", + "integrity": "sha512-ANuA+WXZheGTLW6Veq0i+/B2S4KMhEHAixDv9gQEb9e6FTyqTJVwrqP4CHI3OzA3DZ/ytFf+NTKVofetO/BBQg==", + "dependencies": { + "@turf/distance": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/square-grid": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/square-grid/-/square-grid-7.1.0.tgz", + "integrity": "sha512-JyhsALULVRlkh8htdTi9aXaXFSUv6wRNbeFbqyGJKKlA5eF+AYmyWdI/BlFGQN27xtbtMPeAuLmj+8jaB2omGw==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/rectangle-grid": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/standard-deviational-ellipse": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/standard-deviational-ellipse/-/standard-deviational-ellipse-7.1.0.tgz", + "integrity": "sha512-JqvQFH/witHh+3XgPC1Qk4+3G8w8WQta2NTJjnGinOgFulH+7RD4DcxCT+XXtCHoeq8IvL9VPJRX3ciaW5nSCg==", + "dependencies": { + "@turf/center-mean": "^7.1.0", + "@turf/ellipse": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/meta": "^7.1.0", + "@turf/points-within-polygon": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/tag": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/tag/-/tag-7.1.0.tgz", + "integrity": "sha512-cD8TC++DnNmdI1B/apTf3nj2zRNY6SoLRliB8K76OB+70Kev8tOf4ZVgAqOd0u+Hpdg/T6l7dO7fyJ6UouE7jA==", + "dependencies": { + "@turf/boolean-point-in-polygon": "^7.1.0", + "@turf/clone": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/tesselate": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/tesselate/-/tesselate-7.1.0.tgz", + "integrity": "sha512-E/Z94Mx6kUjvQVbEcSuM9MbEo2dkOczRe4ZzjhFlLgJh1dCkfRgwYLH49mb2CcfG/me1arxoCgmtG+qgm7LrCg==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@types/geojson": "^7946.0.10", + "earcut": "^2.2.4", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/tin": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/tin/-/tin-7.1.0.tgz", + "integrity": "sha512-h8Bdm0IYN6OpKHM8lBRWGxkJnZcxL0KYecf8U6pa6DCEYsEXuEExMTvYSD2OmqIsL5ml8P6RjwgyI+dZeE0O9A==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/transform-rotate": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/transform-rotate/-/transform-rotate-7.1.0.tgz", + "integrity": "sha512-Vp7VBZ6DqaPV8mkwSycksBFRLqSj3y16zg+uEPSCsXUjbFtw9DOLcyH2F5vMpnC2bOpS9NOB4hebhJRwBwAPWQ==", + "dependencies": { + "@turf/centroid": "^7.1.0", + "@turf/clone": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/meta": "^7.1.0", + "@turf/rhumb-bearing": "^7.1.0", + "@turf/rhumb-destination": "^7.1.0", + "@turf/rhumb-distance": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/transform-scale": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/transform-scale/-/transform-scale-7.1.0.tgz", + "integrity": "sha512-m5fLnh3JqrWSv0sAC8Aieet/fr5IZND8BFaE9LakMidtNaJqOIPOyVmUoklcrGn6eK6MX+66rRPn+5a1pahlLQ==", + "dependencies": { + "@turf/bbox": "^7.1.0", + "@turf/center": "^7.1.0", + "@turf/centroid": "^7.1.0", + "@turf/clone": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/meta": "^7.1.0", + "@turf/rhumb-bearing": "^7.1.0", + "@turf/rhumb-destination": "^7.1.0", + "@turf/rhumb-distance": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/transform-translate": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/transform-translate/-/transform-translate-7.1.0.tgz", + "integrity": "sha512-XA6Oh7VqUDrieY9m9/OF4XpBTd8qlfVGi3ObywojCqtHaHKLK3aXwTBZ276i0QKmZqOQA+2jFa9NhgF/TgBDrw==", + "dependencies": { + "@turf/clone": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/meta": "^7.1.0", + "@turf/rhumb-destination": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/triangle-grid": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/triangle-grid/-/triangle-grid-7.1.0.tgz", + "integrity": "sha512-hrPyRAuX5PKu7txmc/11VPKrlJDR+JGzd+eijupKTspNLR4n2sqZUx8UXqSxZ/1nq06ScTyjIfGQJVzlRS8BTg==", + "dependencies": { + "@turf/distance": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/intersect": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/truncate": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/truncate/-/truncate-7.1.0.tgz", + "integrity": "sha512-rrF3AML9PGZw2i5wmt53ESI+Ln9cZyCXgJ7QrEvkT8NbE4OFgmw6p8/1xT8+VEWFSpD4gHz+hmM+5FaFxXvtNg==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/turf": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/turf/-/turf-7.1.0.tgz", + "integrity": "sha512-7NA6tAjbu9oIvIfpRO5AdPrZbFTlUFU02HVA7sLJM9jFeNIZovW09QuDo23uoS2z5l94SXV1GgKKxN5wo7prCw==", + "dependencies": { + "@turf/along": "^7.1.0", + "@turf/angle": "^7.1.0", + "@turf/area": "^7.1.0", + "@turf/bbox": "^7.1.0", + "@turf/bbox-clip": "^7.1.0", + "@turf/bbox-polygon": "^7.1.0", + "@turf/bearing": "^7.1.0", + "@turf/bezier-spline": "^7.1.0", + "@turf/boolean-clockwise": "^7.1.0", + "@turf/boolean-concave": "^7.1.0", + "@turf/boolean-contains": "^7.1.0", + "@turf/boolean-crosses": "^7.1.0", + "@turf/boolean-disjoint": "^7.1.0", + "@turf/boolean-equal": "^7.1.0", + "@turf/boolean-intersects": "^7.1.0", + "@turf/boolean-overlap": "^7.1.0", + "@turf/boolean-parallel": "^7.1.0", + "@turf/boolean-point-in-polygon": "^7.1.0", + "@turf/boolean-point-on-line": "^7.1.0", + "@turf/boolean-touches": "^7.1.0", + "@turf/boolean-valid": "^7.1.0", + "@turf/boolean-within": "^7.1.0", + "@turf/buffer": "^7.1.0", + "@turf/center": "^7.1.0", + "@turf/center-mean": "^7.1.0", + "@turf/center-median": "^7.1.0", + "@turf/center-of-mass": "^7.1.0", + "@turf/centroid": "^7.1.0", + "@turf/circle": "^7.1.0", + "@turf/clean-coords": "^7.1.0", + "@turf/clone": "^7.1.0", + "@turf/clusters": "^7.1.0", + "@turf/clusters-dbscan": "^7.1.0", + "@turf/clusters-kmeans": "^7.1.0", + "@turf/collect": "^7.1.0", + "@turf/combine": "^7.1.0", + "@turf/concave": "^7.1.0", + "@turf/convex": "^7.1.0", + "@turf/destination": "^7.1.0", + "@turf/difference": "^7.1.0", + "@turf/dissolve": "^7.1.0", + "@turf/distance": "^7.1.0", + "@turf/distance-weight": "^7.1.0", + "@turf/ellipse": "^7.1.0", + "@turf/envelope": "^7.1.0", + "@turf/explode": "^7.1.0", + "@turf/flatten": "^7.1.0", + "@turf/flip": "^7.1.0", + "@turf/geojson-rbush": "^7.1.0", + "@turf/great-circle": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/hex-grid": "^7.1.0", + "@turf/interpolate": "^7.1.0", + "@turf/intersect": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@turf/isobands": "^7.1.0", + "@turf/isolines": "^7.1.0", + "@turf/kinks": "^7.1.0", + "@turf/length": "^7.1.0", + "@turf/line-arc": "^7.1.0", + "@turf/line-chunk": "^7.1.0", + "@turf/line-intersect": "^7.1.0", + "@turf/line-offset": "^7.1.0", + "@turf/line-overlap": "^7.1.0", + "@turf/line-segment": "^7.1.0", + "@turf/line-slice": "^7.1.0", + "@turf/line-slice-along": "^7.1.0", + "@turf/line-split": "^7.1.0", + "@turf/line-to-polygon": "^7.1.0", + "@turf/mask": "^7.1.0", + "@turf/meta": "^7.1.0", + "@turf/midpoint": "^7.1.0", + "@turf/moran-index": "^7.1.0", + "@turf/nearest-neighbor-analysis": "^7.1.0", + "@turf/nearest-point": "^7.1.0", + "@turf/nearest-point-on-line": "^7.1.0", + "@turf/nearest-point-to-line": "^7.1.0", + "@turf/planepoint": "^7.1.0", + "@turf/point-grid": "^7.1.0", + "@turf/point-on-feature": "^7.1.0", + "@turf/point-to-line-distance": "^7.1.0", + "@turf/points-within-polygon": "^7.1.0", + "@turf/polygon-smooth": "^7.1.0", + "@turf/polygon-tangents": "^7.1.0", + "@turf/polygon-to-line": "^7.1.0", + "@turf/polygonize": "^7.1.0", + "@turf/projection": "^7.1.0", + "@turf/quadrat-analysis": "^7.1.0", + "@turf/random": "^7.1.0", + "@turf/rectangle-grid": "^7.1.0", + "@turf/rewind": "^7.1.0", + "@turf/rhumb-bearing": "^7.1.0", + "@turf/rhumb-destination": "^7.1.0", + "@turf/rhumb-distance": "^7.1.0", + "@turf/sample": "^7.1.0", + "@turf/sector": "^7.1.0", + "@turf/shortest-path": "^7.1.0", + "@turf/simplify": "^7.1.0", + "@turf/square": "^7.1.0", + "@turf/square-grid": "^7.1.0", + "@turf/standard-deviational-ellipse": "^7.1.0", + "@turf/tag": "^7.1.0", + "@turf/tesselate": "^7.1.0", + "@turf/tin": "^7.1.0", + "@turf/transform-rotate": "^7.1.0", + "@turf/transform-scale": "^7.1.0", + "@turf/transform-translate": "^7.1.0", + "@turf/triangle-grid": "^7.1.0", + "@turf/truncate": "^7.1.0", + "@turf/union": "^7.1.0", + "@turf/unkink-polygon": "^7.1.0", + "@turf/voronoi": "^7.1.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/union": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/union/-/union-7.1.0.tgz", + "integrity": "sha512-7VI8jONdBg9qmbfNlLQycPr93l5aU9HGMgWI9M6pb4ERuU2+p8KgffCgs2NyMtP2HxPrKSybzj31g7bnbEKofQ==", + "dependencies": { + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "polygon-clipping": "^0.15.3", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/unkink-polygon": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/unkink-polygon/-/unkink-polygon-7.1.0.tgz", + "integrity": "sha512-pqkirni2aLpRA1ELFIuJz+mkjYyJQX8Ar6BflSu1b0ajY/CTrcDxbIv1x8UfvbybLzdJc4Gxzg5mo4cEtSwtaQ==", + "dependencies": { + "@turf/area": "^7.1.0", + "@turf/boolean-point-in-polygon": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/meta": "^7.1.0", + "@types/geojson": "^7946.0.10", + "rbush": "^3.0.1", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/voronoi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@turf/voronoi/-/voronoi-7.1.0.tgz", + "integrity": "sha512-xUvzPDG6GaqEekgxd+pjeMKJXOYJ3eFIqUHbTe/ISKzzv3f2cFGiR2VH7ZGXri8d4ozzCQbUQ27ilHPPLf5+xw==", + "dependencies": { + "@turf/clone": "^7.1.0", + "@turf/helpers": "^7.1.0", + "@turf/invariant": "^7.1.0", + "@types/d3-voronoi": "^1.1.12", + "@types/geojson": "^7946.0.10", + "d3-voronoi": "1.1.2", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@tweenjs/tween.js": { + "version": "23.1.3", + "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz", + "integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==" + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "license": "MIT" + }, + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==", + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", + "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, + "node_modules/@types/d3-voronoi": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@types/d3-voronoi/-/d3-voronoi-1.1.12.tgz", + "integrity": "sha512-DauBl25PKZZ0WVJr42a6CNvI6efsdzofl9sajqZr2Gf5Gu733WkDdUGiPkUHXiUvYGzNNlFQde2wdZdfQPG+yw==" + }, + "node_modules/@types/debounce": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/debounce/-/debounce-1.2.4.tgz", + "integrity": "sha512-jBqiORIzKDOToaF63Fm//haOCHuwQuLa2202RK4MozpA6lh93eCBc+/8+wZn5OzjJt3ySdc+74SXWXB55Ewtyw==" + }, + "node_modules/@types/draco3d": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/@types/draco3d/-/draco3d-1.4.10.tgz", + "integrity": "sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw==" + }, + "node_modules/@types/eslint": { + "version": "8.56.12", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz", + "integrity": "sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.1.tgz", + "integrity": "sha512-CRICJIl0N5cXDONAdlTv5ShATZ4HEwk6kDDIW2/w9qOWKg+NU/5F8wYRWCrONad0/UKkloNSmmyN/wX4rtpbVA==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/express/node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/geojson": { + "version": "7946.0.14", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", + "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.6.tgz", + "integrity": "sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==", + "license": "MIT", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "27.5.2", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", + "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", + "dependencies": { + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "node_modules/@types/node": { + "version": "22.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.1.tgz", + "integrity": "sha512-p8Yy/8sw1caA8CdRIQBG5tiLHmxtQKObCijiAa9Ez+d4+PRffM4054xbju0msf+cvhJpnFEeNjxmVT/0ipktrg==", + "dependencies": { + "undici-types": "~6.19.8" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/offscreencanvas": { + "version": "2019.7.3", + "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz", + "integrity": "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==" + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, + "node_modules/@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.13", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", + "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==" + }, + "node_modules/@types/q": { + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.8.tgz", + "integrity": "sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw==" + }, + "node_modules/@types/qs": { + "version": "6.9.16", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", + "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "node_modules/@types/react": { + "version": "18.3.12", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", + "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-reconciler": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.26.7.tgz", + "integrity": "sha512-mBDYl8x+oyPX/VBb3E638N0B7xG+SPk/EAMcVPeexqus/5aTpTphQi0curhhshOqRrc9t6OPoJfEUkbymse/lQ==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-redux": { + "version": "7.1.34", + "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.34.tgz", + "integrity": "sha512-GdFaVjEbYv4Fthm2ZLvj1VSCedV7TqE5y1kNwnjSdBOTXuRSgowux6J8TAct15T3CKBr63UMk+2CO7ilRhyrAQ==", + "license": "MIT", + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.0", + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0", + "redux": "^4.0.0" + } + }, + "node_modules/@types/readable-stream": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.18.tgz", + "integrity": "sha512-21jK/1j+Wg+7jVw1xnSwy/2Q1VgVjWuFssbYGTREPUBeZ+rqVFl2udq0IkxzPC0ZhOzVceUbyIACFZKLqKEBlA==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/@types/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==" + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", + "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", + "dev": true + }, + "node_modules/@types/sizzle": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.9.tgz", + "integrity": "sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w==", + "dev": true + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==" + }, + "node_modules/@types/stats.js": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.3.tgz", + "integrity": "sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==" + }, + "node_modules/@types/testing-library__jest-dom": { + "version": "5.14.9", + "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz", + "integrity": "sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==", + "dependencies": { + "@types/jest": "*" + } + }, + "node_modules/@types/three": { + "version": "0.169.0", + "resolved": "https://registry.npmjs.org/@types/three/-/three-0.169.0.tgz", + "integrity": "sha512-oan7qCgJBt03wIaK+4xPWclYRPG9wzcg7Z2f5T8xYTNEF95kh0t0lklxLLYBDo7gQiGLYzE6iF4ta7nXF2bcsw==", + "dev": true, + "dependencies": { + "@tweenjs/tween.js": "~23.1.3", + "@types/stats.js": "*", + "@types/webxr": "*", + "@webgpu/types": "*", + "fflate": "~0.8.2", + "meshoptimizer": "~0.18.1" + } + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" + }, + "node_modules/@types/webxr": { + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.20.tgz", + "integrity": "sha512-JGpU6qiIJQKUuVSKx1GtQnHJGxRjtfGIhzO2ilq43VZZS//f1h1Sgexbdk+Lq+7569a6EYhOWrUpIruR/1Enmg==" + }, + "node_modules/@types/ws": { + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", + "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "dependencies": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz", + "integrity": "sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==", + "dependencies": { + "@typescript-eslint/utils": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "dependencies": { + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "dependencies": { + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + }, + "node_modules/@use-gesture/core": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/@use-gesture/core/-/core-10.3.1.tgz", + "integrity": "sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw==" + }, + "node_modules/@use-gesture/react": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/@use-gesture/react/-/react-10.3.1.tgz", + "integrity": "sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g==", + "dependencies": { + "@use-gesture/core": "10.3.1" + }, + "peerDependencies": { + "react": ">= 16.8.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "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" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "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" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "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" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "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" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webgpu/types": { + "version": "0.1.49", + "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.49.tgz", + "integrity": "sha512-NMmS8/DofhH/IFeW+876XrHVWel+J/vdcFCHLDqeJgkH9x0DeiwjVd8LcBdaxdG/T7Rf8VUAYsA8X1efMzLjRQ==", + "dev": true + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead" + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.9.tgz", + "integrity": "sha512-ozbS3LuenHVxNRh/wdnN16QapUHzauqSomAl1jwwJRRsGwFwtj644lIhxfWu0Fy0acCij2+AEgHvjscq3dlVXg==", + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.reduce": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.7.tgz", + "integrity": "sha512-mzmiUCVwtiD4lgxYP8g7IYy8El8p2CSMePvIbTS7gchKir/L1fgJrk0yDKmAX6mnRQFKNADYIk8nNlTris5H1Q==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-array-method-boxes-properly": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "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" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==" + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/attr-accept": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.5.tgz", + "integrity": "sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", + "dev": true + }, + "node_modules/axe-core": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.2.tgz", + "integrity": "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==", + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "dependencies": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-loader": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.4.1.tgz", + "integrity": "sha512-nXzRChX+Z1GoE6yWavBQg6jDslyFF3SDjl2paADuoQtQW10JqShJt62R6eJQ5m/pjJFDT8xgKIWSP85OY8eXeA==", + "dependencies": { + "find-cache-dir": "^3.3.1", + "loader-utils": "^2.0.4", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + }, + "engines": { + "node": ">= 8.9" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "webpack": ">=2" + } + }, + "node_modules/babel-loader/node_modules/schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dependencies": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-named-asset-import": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", + "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", + "peerDependencies": { + "@babel/core": "^7.1.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-transform-react-remove-prop-types": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", + "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==" + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", + "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "dependencies": { + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-react-app": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-10.0.1.tgz", + "integrity": "sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==", + "dependencies": { + "@babel/core": "^7.16.0", + "@babel/plugin-proposal-class-properties": "^7.16.0", + "@babel/plugin-proposal-decorators": "^7.16.4", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0", + "@babel/plugin-proposal-numeric-separator": "^7.16.0", + "@babel/plugin-proposal-optional-chaining": "^7.16.0", + "@babel/plugin-proposal-private-methods": "^7.16.0", + "@babel/plugin-transform-flow-strip-types": "^7.16.0", + "@babel/plugin-transform-react-display-name": "^7.16.0", + "@babel/plugin-transform-runtime": "^7.16.4", + "@babel/preset-env": "^7.16.4", + "@babel/preset-react": "^7.16.0", + "@babel/preset-typescript": "^7.16.0", + "@babel/runtime": "^7.16.3", + "babel-plugin-macros": "^3.1.0", + "babel-plugin-transform-react-remove-prop-types": "^0.4.24" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/bfj": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.1.0.tgz", + "integrity": "sha512-I6MMLkn+anzNdCUp9hMRyui1HaNEUCco50lxbvNS4+EyXg8lN3nJ48PjPWtbH8UVS9CuMoaKE9U2V3l29DaRQw==", + "dependencies": { + "bluebird": "^3.7.2", + "check-types": "^11.2.3", + "hoopy": "^0.1.4", + "jsonpath": "^1.1.1", + "tryer": "^1.0.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bl": { + "version": "6.0.16", + "resolved": "https://registry.npmjs.org/bl/-/bl-6.0.16.tgz", + "integrity": "sha512-V/kz+z2Mx5/6qDfRCilmrukUXcXuCoXKg3/3hDvzKKoSUx8CJKudfIoT29XZc3UE9xBvxs5qictiHdprwtteEg==", + "license": "MIT", + "dependencies": { + "@types/readable-stream": "^4.0.0", + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^4.2.0" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/blob-util": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", + "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", + "dev": true + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/bonjour-service": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" + }, + "node_modules/browserslist": { + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cachedir": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", + "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/camera-controls": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/camera-controls/-/camera-controls-2.9.0.tgz", + "integrity": "sha512-TpCujnP0vqPppTXXJRYpvIy0xq9Tro6jQf2iYUxlDpPCNxkvE/XGaTuwIxnhINOkVP/ob2CRYXtY3iVYXeMEzA==", + "peerDependencies": { + "three": ">=0.126.1" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001673", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001673.tgz", + "integrity": "sha512-WTrjUCSMp3LYX0nE12ECkV0a+e6LC85E0Auz75555/qr78Oc8YWhEPNfDd6SHdtlCMSzqtuXY0uyEMNRcsKpKw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/case-sensitive-paths-webpack-plugin": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", + "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/chart.js": { + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.8.tgz", + "integrity": "sha512-IkGZlVpXP+83QpMm4uxEiGqSI7jFizwVtF3+n5Pc3k7sMO+tkd0qxh2OzLhenM0K80xtmAONWGBn082EiBQSDA==", + "license": "MIT", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } + }, + "node_modules/check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/check-types": { + "version": "11.2.3", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz", + "integrity": "sha512-+67P1GkJRaxQD6PKK0Et9DhwQB+vGg3PM5+aavopCpZT1lj9jeqfvpgTLAWErNj8qApkkmXlu/Ug74kmhagkXg==" + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz", + "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==" + }, + "node_modules/classnames": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==", + "license": "MIT" + }, + "node_modules/clean-css": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "dependencies": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/coa/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/coa/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/coa/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/commist": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz", + "integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==", + "license": "MIT" + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "engines": [ + "node >= 6.0" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concaveman": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/concaveman/-/concaveman-1.2.1.tgz", + "integrity": "sha512-PwZYKaM/ckQSa8peP5JpVr7IMJ4Nn/MHIaWUjP4be+KoZ7Botgs8seAZGpmaOM+UZXawcdYRao/px9ycrCihHw==", + "dependencies": { + "point-in-polygon": "^1.1.0", + "rbush": "^3.0.1", + "robust-predicates": "^2.0.4", + "tinyqueue": "^2.0.3" + } + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/core-js": { + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.1.tgz", + "integrity": "sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz", + "integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==", + "dependencies": { + "browserslist": "^4.23.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-pure": { + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.38.1.tgz", + "integrity": "sha512-BY8Etc1FZqdw1glX0XNOq2FDwfrg/VGqoZOZCdaL+UmdaqDwQwYXkMJT4t6In+zfEfOJDcM9T0KdbBeJg8KKCQ==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/css-blank-pseudo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", + "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "bin": { + "css-blank-pseudo": "dist/cli.cjs" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-box-model": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz", + "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==", + "license": "MIT", + "dependencies": { + "tiny-invariant": "^1.0.6" + } + }, + "node_modules/css-declaration-sorter": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", + "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-has-pseudo": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", + "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "bin": { + "css-has-pseudo": "dist/cli.cjs" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-loader": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", + "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-minimizer-webpack-plugin": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", + "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", + "dependencies": { + "cssnano": "^5.0.6", + "jest-worker": "^27.0.2", + "postcss": "^8.3.5", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@parcel/css": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-prefers-color-scheme": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", + "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", + "bin": { + "css-prefers-color-scheme": "dist/cli.cjs" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" + }, + "node_modules/css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "dependencies": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-tree/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==" + }, + "node_modules/cssdb": { + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.11.2.tgz", + "integrity": "sha512-lhQ32TFkc1X4eTefGfYPvgovRSzIMofHkigfH8nWtyRL4XJLsRhJFreRvEgKzept7x1rjBuy3J/MurXLaFxW/A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + } + ] + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", + "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", + "dependencies": { + "cssnano-preset-default": "^5.2.14", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-preset-default": { + "version": "5.2.14", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", + "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", + "dependencies": { + "css-declaration-sorter": "^6.3.1", + "cssnano-utils": "^3.1.0", + "postcss-calc": "^8.2.3", + "postcss-colormin": "^5.3.1", + "postcss-convert-values": "^5.1.3", + "postcss-discard-comments": "^5.1.2", + "postcss-discard-duplicates": "^5.1.0", + "postcss-discard-empty": "^5.1.1", + "postcss-discard-overridden": "^5.1.0", + "postcss-merge-longhand": "^5.1.7", + "postcss-merge-rules": "^5.1.4", + "postcss-minify-font-values": "^5.1.0", + "postcss-minify-gradients": "^5.1.1", + "postcss-minify-params": "^5.1.4", + "postcss-minify-selectors": "^5.2.1", + "postcss-normalize-charset": "^5.1.0", + "postcss-normalize-display-values": "^5.1.0", + "postcss-normalize-positions": "^5.1.1", + "postcss-normalize-repeat-style": "^5.1.1", + "postcss-normalize-string": "^5.1.0", + "postcss-normalize-timing-functions": "^5.1.0", + "postcss-normalize-unicode": "^5.1.1", + "postcss-normalize-url": "^5.1.0", + "postcss-normalize-whitespace": "^5.1.1", + "postcss-ordered-values": "^5.1.3", + "postcss-reduce-initial": "^5.1.2", + "postcss-reduce-transforms": "^5.1.0", + "postcss-svgo": "^5.1.0", + "postcss-unique-selectors": "^5.1.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + }, + "node_modules/csso/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/cypress": { + "version": "13.15.1", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.15.1.tgz", + "integrity": "sha512-DwUFiKXo4lef9kA0M4iEhixFqoqp2hw8igr0lTqafRb9qtU3X0XGxKbkSYsUFdkrAkphc7MPDxoNPhk5pj9PVg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@cypress/request": "^3.0.4", + "@cypress/xvfb": "^1.2.4", + "@types/sinonjs__fake-timers": "8.1.1", + "@types/sizzle": "^2.3.2", + "arch": "^2.2.0", + "blob-util": "^2.0.2", + "bluebird": "^3.7.2", + "buffer": "^5.7.1", + "cachedir": "^2.3.0", + "chalk": "^4.1.0", + "check-more-types": "^2.24.0", + "cli-cursor": "^3.1.0", + "cli-table3": "~0.6.1", + "commander": "^6.2.1", + "common-tags": "^1.8.0", + "dayjs": "^1.10.4", + "debug": "^4.3.4", + "enquirer": "^2.3.6", + "eventemitter2": "6.4.7", + "execa": "4.1.0", + "executable": "^4.1.1", + "extract-zip": "2.0.1", + "figures": "^3.2.0", + "fs-extra": "^9.1.0", + "getos": "^3.2.1", + "is-ci": "^3.0.1", + "is-installed-globally": "~0.4.0", + "lazy-ass": "^1.6.0", + "listr2": "^3.8.3", + "lodash": "^4.17.21", + "log-symbols": "^4.0.0", + "minimist": "^1.2.8", + "ospath": "^1.2.2", + "pretty-bytes": "^5.6.0", + "process": "^0.11.10", + "proxy-from-env": "1.0.0", + "request-progress": "^3.0.0", + "semver": "^7.5.3", + "supports-color": "^8.1.1", + "tmp": "~0.2.3", + "tree-kill": "1.2.2", + "untildify": "^4.0.0", + "yauzl": "^2.10.0" + }, + "bin": { + "cypress": "bin/cypress" + }, + "engines": { + "node": "^16.0.0 || ^18.0.0 || >=20.0.0" + } + }, + "node_modules/cypress/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/cypress/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/d3-array": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", + "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==" + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.7.1.tgz", + "integrity": "sha512-O4AempWAr+P5qbk2bC2FuN/sDW4z+dN2wDf9QV3bxQt4M5HfOEeXLgJ/UKQW0+o1Dj8BE+L5kiDbdWUMjsmQpw==", + "dependencies": { + "d3-array": "1" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale/node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time/node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-voronoi": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.2.tgz", + "integrity": "sha512-RhGS1u2vavcO7ay7ZNAPo4xeDh/VYeGof3x5ZLJBQgYhLegxr3s5IykvWmJ94FTU6mcbtp4sloqZ54mP6R4Utw==" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", + "dev": true + }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" + }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==", + "license": "MIT" + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==" + }, + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/default-gateway/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/default-gateway/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-gateway/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-gpu": { + "version": "5.0.54", + "resolved": "https://registry.npmjs.org/detect-gpu/-/detect-gpu-5.0.54.tgz", + "integrity": "sha512-mPfxFyfiJraOkxtDe/oaSzCt21QAmNmFtcaN7te41SwAZ2UbBsC526kAaSY6EosniNUL/K0pzh1cjqgZ3fN45A==", + "dependencies": { + "webgl-constants": "^1.1.1" + } + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + }, + "node_modules/detect-port-alt": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", + "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", + "dependencies": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "bin": { + "detect": "bin/detect-port", + "detect-port": "bin/detect-port" + }, + "engines": { + "node": ">= 4.2.1" + } + }, + "node_modules/detect-port-alt/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/detect-port-alt/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==" + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "deprecated": "Use your platform's native DOMException instead", + "dependencies": { + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" + }, + "node_modules/draco3d": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.7.tgz", + "integrity": "sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ==" + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, + "node_modules/earcut": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", + "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.47", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.47.tgz", + "integrity": "sha512-zS5Yer0MOYw4rtK2iq43cJagHZ8sXN0jDHDKzB+86gSBSAI4v07S97mcq+Gs2vclAxSh1j7vOAHxSVgduiiuVQ==" + }, + "node_modules/emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/engine.io-client": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.2.tgz", + "integrity": "sha512-TAr+NKeoVTjEVW8P3iHguO1LO6RlUz9O5Y8o7EY0fU+gY1NYqas7NN3slpFtbXEsLMHk0h90fJMfKjRkQ0qUIw==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1", + "xmlhttprequest-ssl": "~2.1.1" + } + }, + "node_modules/engine.io-client/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "dependencies": { + "stackframe": "^1.3.4" + } + }, + "node_modules/es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "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.3", + "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.1", + "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" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.1.0.tgz", + "integrity": "sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==", + "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.3", + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==" + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-react-app": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", + "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", + "dependencies": { + "@babel/core": "^7.16.0", + "@babel/eslint-parser": "^7.16.3", + "@rushstack/eslint-patch": "^1.1.0", + "@typescript-eslint/eslint-plugin": "^5.5.0", + "@typescript-eslint/parser": "^5.5.0", + "babel-preset-react-app": "^10.0.1", + "confusing-browser-globals": "^1.0.11", + "eslint-plugin-flowtype": "^8.0.3", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jest": "^25.3.0", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.27.1", + "eslint-plugin-react-hooks": "^4.3.0", + "eslint-plugin-testing-library": "^5.0.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "eslint": "^8.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-flowtype": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", + "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", + "dependencies": { + "lodash": "^4.17.21", + "string-natural-compare": "^3.0.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@babel/plugin-syntax-flow": "^7.14.5", + "@babel/plugin-transform-react-jsx": "^7.14.9", + "eslint": "^8.1.0" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "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-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.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", + "string.prototype.trimend": "^1.0.8", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jest": { + "version": "25.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", + "integrity": "sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==", + "dependencies": { + "@typescript-eslint/experimental-utils": "^5.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^4.0.0 || ^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", + "dependencies": { + "aria-query": "^5.3.2", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "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.1" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.2.tgz", + "integrity": "sha512-EsTAnj9fLVr/GZleBLFbj/sSuXeWmp1eXIN60ceYnZveqEaUCyW4X+Vh4WTdUhCkW4xutXYqTXCUSyqD4rB75w==", + "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.1.0", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "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" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "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" + } + }, + "node_modules/eslint-plugin-react/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-testing-library": { + "version": "5.11.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.1.tgz", + "integrity": "sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw==", + "dependencies": { + "@typescript-eslint/utils": "^5.58.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0", + "npm": ">=6" + }, + "peerDependencies": { + "eslint": "^7.5.0 || ^8.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-webpack-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz", + "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==", + "dependencies": { + "@types/eslint": "^7.29.0 || ^8.4.1", + "jest-worker": "^28.0.2", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0", + "webpack": "^5.0.0" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/eslint/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter2": { + "version": "6.4.7", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", + "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==", + "dev": true + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "dependencies": { + "pify": "^2.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "dependencies": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/express": { + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.10", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend-shallow/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-equals": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.2.2.tgz", + "integrity": "sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "node_modules/fast-unique-numbers": { + "version": "8.0.13", + "resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-8.0.13.tgz", + "integrity": "sha512-7OnTFAVPefgw2eBJ1xj2PGGR9FwYzSUso9decayHgCDX4sJkHLdcsYTytTg+tYv+wKF3U8gJuSBz2jJpQV4u/g==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.1.0" + } + }, + "node_modules/fast-uri": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==" + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==" + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/file-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/file-selector": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.5.0.tgz", + "integrity": "sha512-s8KNnmIDTBoD0p9uJ9uD0XY38SCeBOtj0UMXyQSLg1Ypfrfj8+dAvwsLjYQkQ2GjhVtp2HrnF5cJzMhBjfD8HA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/filesize": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", + "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==" + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", + "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "chokidar": "^3.4.2", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "glob": "^7.1.6", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=10", + "yarn": ">=1.0.0" + }, + "peerDependencies": { + "eslint": ">= 6", + "typescript": ">= 2.7", + "vue-template-compiler": "*", + "webpack": ">= 4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + }, + "vue-template-compiler": { + "optional": true + } + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dependencies": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", + "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/geojson-equality-ts": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/geojson-equality-ts/-/geojson-equality-ts-1.0.2.tgz", + "integrity": "sha512-h3Ryq+0mCSN/7yLs0eDgrZhvc9af23o/QuC4aTiuuzP/MRCtd6mf5rLsLRY44jX0RPUfM8c4GqERQmlUxPGPoQ==", + "dependencies": { + "@types/geojson": "^7946.0.14" + } + }, + "node_modules/geojson-polygon-self-intersections": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/geojson-polygon-self-intersections/-/geojson-polygon-self-intersections-1.2.1.tgz", + "integrity": "sha512-/QM1b5u2d172qQVO//9CGRa49jEmclKEsYOQmWP9ooEjj63tBM51m2805xsbxkzlEELQ2REgTf700gUhhlegxA==", + "dependencies": { + "rbush": "^2.0.1" + } + }, + "node_modules/geojson-polygon-self-intersections/node_modules/quickselect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-1.1.1.tgz", + "integrity": "sha512-qN0Gqdw4c4KGPsBOQafj6yj/PA6c/L63f6CaZ/DCF/xF4Esu3jVmKLUDYxghFx8Kb/O7y9tI7x2RjTSXwdK1iQ==" + }, + "node_modules/geojson-polygon-self-intersections/node_modules/rbush": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/rbush/-/rbush-2.0.2.tgz", + "integrity": "sha512-XBOuALcTm+O/H8G90b6pzu6nX6v2zCKiFG4BJho8a+bY6AER6t8uQUZdi5bomQc0AprCWhEGa7ncAbbRap0bRA==", + "dependencies": { + "quickselect": "^1.0.1" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/getos": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", + "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", + "dev": true, + "dependencies": { + "async": "^3.2.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", + "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, + "node_modules/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "dev": true, + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glsl-noise": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/glsl-noise/-/glsl-noise-0.0.0.tgz", + "integrity": "sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w==" + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" + }, + "node_modules/gsap": { + "version": "3.12.5", + "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.12.5.tgz", + "integrity": "sha512-srBfnk4n+Oe/ZnMIOXt3gT605BX9x5+rh/prT2F1SsNJsU1XuMiP0E2aptW481OnonOGACZWBqseH5Z7csHxhQ==" + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" + }, + "node_modules/harmony-reflect": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", + "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==" + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, + "node_modules/help-me": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", + "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==", + "license": "MIT" + }, + "node_modules/hls.js": { + "version": "1.5.17", + "resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.5.17.tgz", + "integrity": "sha512-wA66nnYFvQa1o4DO/BFgLNRKnBTVXpNeldGRBJ2Y0SvFtdwvFKCbqa9zhHoZLoxHhZ+jYsj3aIBkWQQCPNOhMw==" + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.3.tgz", + "integrity": "sha512-QSf1yjtSAsmf7rYBV7XX86uua4W/vkhIt0xNXKbsi2foEeW7vjJQz4bhnpL3xH+l1ryl1680uNv968Z+X6jSYg==", + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/http-signature": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz", + "integrity": "sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.18.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/husky": { + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.6.tgz", + "integrity": "sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==", + "dev": true, + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/identity-obj-proxy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", + "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", + "dependencies": { + "harmony-reflect": "^1.4.6" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" + }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/immutable": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", + "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==" + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "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.", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-root": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", + "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/iterator.prototype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.3.tgz", + "integrity": "sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==", + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/its-fine": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/its-fine/-/its-fine-1.2.5.tgz", + "integrity": "sha512-fXtDA0X0t0eBYAGLVM5YsgJGsJ5jEmqZEPrGbzdf5awjv0xE7nqv3TVnvtUF060Tkes15DbDAKW/I48vsb6SyA==", + "dependencies": { + "@types/react-reconciler": "^0.28.0" + }, + "peerDependencies": { + "react": ">=18.0" + } + }, + "node_modules/its-fine/node_modules/@types/react-reconciler": { + "version": "0.28.8", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.8.tgz", + "integrity": "sha512-SN9c4kxXZonFhbX4hJrZy37yw9e7EIxcpHCxQv5JUS18wDE5ovkQKlqQEkufdJCCMfuI9BnjUJvhYeJ9x5Ra7g==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/jackspeak": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz", + "integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/jake/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", + "dependencies": { + "@jest/core": "^27.5.1", + "import-local": "^3.0.2", + "jest-cli": "^27.5.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", + "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", + "dependencies": { + "@jest/types": "^27.5.1", + "execa": "^5.0.0", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-changed-files/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/jest-changed-files/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-changed-files/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/jest-circus": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", + "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-cli": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", + "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", + "dependencies": { + "@jest/core": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", + "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", + "dependencies": { + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.5.1", + "@jest/types": "^27.5.1", + "babel-jest": "^27.5.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.9", + "jest-circus": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-jasmine2": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/jest-config/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-config/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", + "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", + "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", + "dependencies": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", + "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1", + "jsdom": "^16.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", + "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-jasmine2": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", + "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-leak-detector": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", + "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", + "dependencies": { + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-mock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", + "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", + "dependencies": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", + "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", + "dependencies": { + "@jest/types": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-snapshot": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runner": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", + "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-leak-detector": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", + "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/globals": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/jest-runtime/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-runtime/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-runtime/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/jest-runtime/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jest-serializer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", + "dependencies": { + "@types/node": "*", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", + "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", + "dependencies": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^27.5.1", + "semver": "^7.3.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-validate": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", + "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", + "dependencies": { + "@jest/types": "^27.5.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "leven": "^3.1.0", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-watch-typeahead": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz", + "integrity": "sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw==", + "dependencies": { + "ansi-escapes": "^4.3.1", + "chalk": "^4.0.0", + "jest-regex-util": "^28.0.0", + "jest-watcher": "^28.0.0", + "slash": "^4.0.0", + "string-length": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "jest": "^27.0.0 || ^28.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/console": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", + "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/console/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/test-result": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", + "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", + "dependencies": { + "@jest/console": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/types": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-watch-typeahead/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/emittery": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", + "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-message-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-message-util/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-regex-util": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-watcher": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", + "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", + "dependencies": { + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "jest-util": "^28.1.3", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-watcher/node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-watcher/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + }, + "node_modules/jest-watch-typeahead/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watch-typeahead/node_modules/string-length": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz", + "integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==", + "dependencies": { + "char-regex": "^2.0.0", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watch-typeahead/node_modules/string-length/node_modules/char-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz", + "integrity": "sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/jest-watch-typeahead/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/jest-watcher": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", + "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", + "dependencies": { + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.5.1", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-sdsl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, + "node_modules/jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/form-data": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.2.tgz", + "integrity": "sha512-sJe+TQb2vIaIyO783qN6BlMYWMw3WBOHA1Ay2qxsnjuafEOQFJ2JakedOQirT6D5XPRxDvS7AHYyem9fTpb4LQ==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonpath": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", + "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", + "dependencies": { + "esprima": "1.2.2", + "static-eval": "2.0.2", + "underscore": "1.12.1" + } + }, + "node_modules/jsonpath/node_modules/esprima": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", + "integrity": "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jsprim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", + "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "node_modules/jsts": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/jsts/-/jsts-2.7.1.tgz", + "integrity": "sha512-x2wSZHEBK20CY+Wy+BPE7MrFQHW6sIsdaGUMEqmGAio+3gFzQaBYPwLRonUfQf9Ak8pBieqj9tUofX1+WtAEIg==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/klona": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==" + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/launch-editor": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", + "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", + "dev": true, + "engines": { + "node": "> 0.8" + } + }, + "node_modules/leva": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/leva/-/leva-0.10.0.tgz", + "integrity": "sha512-RiNJWmeqQdKIeHuVXgshmxIHu144a2AMYtLxKf8Nm1j93pisDPexuQDHKNdQlbo37wdyDQibLjY9JKGIiD7gaw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-portal": "1.0.2", + "@radix-ui/react-tooltip": "1.0.5", + "@stitches/react": "^1.2.8", + "@use-gesture/react": "^10.2.5", + "colord": "^2.9.2", + "dequal": "^2.0.2", + "merge-value": "^1.0.0", + "react-colorful": "^5.5.1", + "react-dropzone": "^12.0.0", + "v8n": "^1.3.3", + "zustand": "^3.6.9" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/leva/node_modules/zustand": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", + "integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==", + "license": "MIT", + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/listr2": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", + "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", + "dev": true, + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.1", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "dev": true + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.1.tgz", + "integrity": "sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/maath": { + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/maath/-/maath-0.10.8.tgz", + "integrity": "sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g==", + "peerDependencies": { + "@types/three": ">=0.134.0", + "three": ">=0.134.0" + } + }, + "node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/marchingsquares": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/marchingsquares/-/marchingsquares-1.3.3.tgz", + "integrity": "sha512-gz6nNQoVK7Lkh2pZulrT4qd4347S/toG9RXH2pyzhLgkL5mLkBoqgv4EvAGXcV0ikDW72n/OQb3Xe8bGagQZCg==" + }, + "node_modules/mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", + "license": "MIT" + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/merge-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/merge-value/-/merge-value-1.0.0.tgz", + "integrity": "sha512-fJMmvat4NeKz63Uv9iHWcPDjCWcCkoiRoajRTEO8hlhUC6rwaHg0QCF9hBOTjZmm4JuglPckPSTtcuJL5kp0TQ==", + "license": "MIT", + "dependencies": { + "get-value": "^2.0.6", + "is-extendable": "^1.0.0", + "mixin-deep": "^1.2.0", + "set-value": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/meshline": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/meshline/-/meshline-3.3.1.tgz", + "integrity": "sha512-/TQj+JdZkeSUOl5Mk2J7eLcYTLiQm2IDzmlSvYm7ov15anEcDJ92GHqqazxTSreeNgfnYu24kiEvvv0WlbCdFQ==", + "peerDependencies": { + "three": ">=0.137" + } + }, + "node_modules/meshoptimizer": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.18.1.tgz", + "integrity": "sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.1.tgz", + "integrity": "sha512-+Vyi+GCCOHnrJ2VPS+6aPoXN2k2jgUzDRhTFLjjTBn23qyXJXkjUWQgTL+mXpF5/A8ixLdCc6kWsoeOjKGejKQ==", + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimatch": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "license": "MIT", + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mqtt": { + "version": "5.10.3", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.10.3.tgz", + "integrity": "sha512-hA/6YrUS4fywhBGCjH/XXUuLeueJiPqruVVWjK2A24Ma4KcWfZ/x8x07aoesBV+HXDWBC08tbT4IWfSXNW0Jtw==", + "license": "MIT", + "dependencies": { + "@types/readable-stream": "^4.0.5", + "@types/ws": "^8.5.9", + "commist": "^3.2.0", + "concat-stream": "^2.0.0", + "debug": "^4.3.4", + "help-me": "^5.0.0", + "lru-cache": "^10.0.1", + "minimist": "^1.2.8", + "mqtt-packet": "^9.0.1", + "number-allocator": "^1.0.14", + "readable-stream": "^4.4.2", + "reinterval": "^1.1.0", + "rfdc": "^1.3.0", + "split2": "^4.2.0", + "worker-timers": "^7.1.4", + "ws": "^8.17.1" + }, + "bin": { + "mqtt": "build/bin/mqtt.js", + "mqtt_pub": "build/bin/pub.js", + "mqtt_sub": "build/bin/sub.js" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/mqtt-packet": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-9.0.1.tgz", + "integrity": "sha512-koZF1V/X2RZUI6uD9wN5OK1JxxcG1ofAR4H3LjCw1FkeKzruZQ26aAA6v2m1lZyWONZIR5wMMJFrZJDRNzbiQw==", + "license": "MIT", + "dependencies": { + "bl": "^6.0.8", + "debug": "^4.3.4", + "process-nextick-args": "^2.0.1" + } + }, + "node_modules/mqtt/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/mqtt/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/mqtt/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/n8ao": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/n8ao/-/n8ao-1.9.3.tgz", + "integrity": "sha512-OZX+u8LaEfxLi6lupuyT8gIv80D6D8FIeKbBNkCyY0nE+1wmm6sQ4yeyW3a15lFMrfTcEhe0AU8QhhDejHg7sg==", + "license": "ISC", + "peerDependencies": { + "postprocessing": ">=6.30.0", + "three": ">=0.137" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==" + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/number-allocator": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz", + "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.1", + "js-sdsl": "4.3.0" + } + }, + "node_modules/nwsapi": { + "version": "2.2.13", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.13.tgz", + "integrity": "sha512-cTGB9ptp9dY9A5VbMSe7fQBcl/tt22Vcqdq8+eN93rblOuE0aCFu4aZ2vMwct/2t+lFnosm8RkQW1I0Omb1UtQ==" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.8.tgz", + "integrity": "sha512-qkHIGe4q0lSYMv0XI4SsBTJz3WaURhLvd0lKSgtVuOsJ2krg4SgMw3PIRQFMp07yi++UR3se2mkcLqsBNpBb/A==", + "dependencies": { + "array.prototype.reduce": "^1.0.6", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "gopd": "^1.0.1", + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ospath": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", + "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", + "dev": true + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==" + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/point-in-polygon": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/point-in-polygon/-/point-in-polygon-1.1.0.tgz", + "integrity": "sha512-3ojrFwjnnw8Q9242TzgXuTD+eKiutbzyslcq1ydfu82Db2y+Ogbmyrkpv0Hgj31qwT3lbS9+QAAO/pIQM35XRw==" + }, + "node_modules/point-in-polygon-hao": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/point-in-polygon-hao/-/point-in-polygon-hao-1.1.0.tgz", + "integrity": "sha512-3hTIM2j/v9Lio+wOyur3kckD4NxruZhpowUbEgmyikW+a2Kppjtu1eN+AhnMQtoHW46zld88JiYWv6fxpsDrTQ==" + }, + "node_modules/polygon-clipping": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/polygon-clipping/-/polygon-clipping-0.15.7.tgz", + "integrity": "sha512-nhfdr83ECBg6xtqOAJab1tbksbBAOMUltN60bU+llHVOL0e5Onm1WpAXXWXVB39L8AJFssoIhEVuy/S90MmotA==", + "dependencies": { + "robust-predicates": "^3.0.2", + "splaytree": "^3.1.0" + } + }, + "node_modules/polygon-clipping/node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-attribute-case-insensitive": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz", + "integrity": "sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-browser-comments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", + "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==", + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "browserslist": ">=4", + "postcss": ">=8" + } + }, + "node_modules/postcss-calc": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", + "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "dependencies": { + "postcss-selector-parser": "^6.0.9", + "postcss-value-parser": "^4.2.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-clamp": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", + "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=7.6.0" + }, + "peerDependencies": { + "postcss": "^8.4.6" + } + }, + "node_modules/postcss-color-functional-notation": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz", + "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-color-hex-alpha": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz", + "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-color-rebeccapurple": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz", + "integrity": "sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-colormin": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", + "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-convert-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", + "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-custom-media": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz", + "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.3" + } + }, + "node_modules/postcss-custom-properties": { + "version": "12.1.11", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz", + "integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-custom-selectors": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz", + "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==", + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.3" + } + }, + "node_modules/postcss-dir-pseudo-class": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz", + "integrity": "sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-discard-comments": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", + "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-empty": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-double-position-gradients": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz", + "integrity": "sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-env-function": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.6.tgz", + "integrity": "sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-flexbugs-fixes": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", + "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", + "peerDependencies": { + "postcss": "^8.1.4" + } + }, + "node_modules/postcss-focus-visible": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", + "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-within": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", + "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-font-variant": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-gap-properties": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", + "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==", + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-image-set-function": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz", + "integrity": "sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-initial": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", + "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-lab-function": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz", + "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", + "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/postcss-loader": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz", + "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==", + "dependencies": { + "cosmiconfig": "^7.0.0", + "klona": "^2.0.5", + "semver": "^7.3.5" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + } + }, + "node_modules/postcss-logical": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", + "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-media-minmax": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", + "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", + "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^5.1.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-merge-rules": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", + "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^3.1.0", + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", + "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", + "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", + "dependencies": { + "colord": "^2.9.1", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-params": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", + "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", + "dependencies": { + "browserslist": "^4.21.4", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", + "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", + "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", + "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-nesting": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", + "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", + "dependencies": { + "@csstools/selector-specificity": "^2.0.0", + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-normalize": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-10.0.1.tgz", + "integrity": "sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA==", + "dependencies": { + "@csstools/normalize.css": "*", + "postcss-browser-comments": "^4", + "sanitize.css": "*" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "browserslist": ">= 4", + "postcss": ">= 8" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", + "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", + "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", + "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-string": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", + "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", + "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", + "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", + "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", + "dependencies": { + "normalize-url": "^6.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", + "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-opacity-percentage": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz", + "integrity": "sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==", + "funding": [ + { + "type": "kofi", + "url": "https://ko-fi.com/mrcgrtz" + }, + { + "type": "liberapay", + "url": "https://liberapay.com/mrcgrtz" + } + ], + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-ordered-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", + "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", + "dependencies": { + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-overflow-shorthand": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz", + "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-page-break": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", + "peerDependencies": { + "postcss": "^8" + } + }, + "node_modules/postcss-place": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz", + "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-preset-env": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz", + "integrity": "sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag==", + "dependencies": { + "@csstools/postcss-cascade-layers": "^1.1.1", + "@csstools/postcss-color-function": "^1.1.1", + "@csstools/postcss-font-format-keywords": "^1.0.1", + "@csstools/postcss-hwb-function": "^1.0.2", + "@csstools/postcss-ic-unit": "^1.0.1", + "@csstools/postcss-is-pseudo-class": "^2.0.7", + "@csstools/postcss-nested-calc": "^1.0.0", + "@csstools/postcss-normalize-display-values": "^1.0.1", + "@csstools/postcss-oklab-function": "^1.1.1", + "@csstools/postcss-progressive-custom-properties": "^1.3.0", + "@csstools/postcss-stepped-value-functions": "^1.0.1", + "@csstools/postcss-text-decoration-shorthand": "^1.0.0", + "@csstools/postcss-trigonometric-functions": "^1.0.2", + "@csstools/postcss-unset-value": "^1.0.2", + "autoprefixer": "^10.4.13", + "browserslist": "^4.21.4", + "css-blank-pseudo": "^3.0.3", + "css-has-pseudo": "^3.0.4", + "css-prefers-color-scheme": "^6.0.3", + "cssdb": "^7.1.0", + "postcss-attribute-case-insensitive": "^5.0.2", + "postcss-clamp": "^4.1.0", + "postcss-color-functional-notation": "^4.2.4", + "postcss-color-hex-alpha": "^8.0.4", + "postcss-color-rebeccapurple": "^7.1.1", + "postcss-custom-media": "^8.0.2", + "postcss-custom-properties": "^12.1.10", + "postcss-custom-selectors": "^6.0.3", + "postcss-dir-pseudo-class": "^6.0.5", + "postcss-double-position-gradients": "^3.1.2", + "postcss-env-function": "^4.0.6", + "postcss-focus-visible": "^6.0.4", + "postcss-focus-within": "^5.0.4", + "postcss-font-variant": "^5.0.0", + "postcss-gap-properties": "^3.0.5", + "postcss-image-set-function": "^4.0.7", + "postcss-initial": "^4.0.1", + "postcss-lab-function": "^4.2.1", + "postcss-logical": "^5.0.4", + "postcss-media-minmax": "^5.0.0", + "postcss-nesting": "^10.2.0", + "postcss-opacity-percentage": "^1.1.2", + "postcss-overflow-shorthand": "^3.0.4", + "postcss-page-break": "^3.0.4", + "postcss-place": "^7.0.5", + "postcss-pseudo-class-any-link": "^7.1.6", + "postcss-replace-overflow-wrap": "^4.0.0", + "postcss-selector-not": "^6.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-pseudo-class-any-link": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz", + "integrity": "sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", + "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", + "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-replace-overflow-wrap": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", + "peerDependencies": { + "postcss": "^8.0.3" + } + }, + "node_modules/postcss-selector-not": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz", + "integrity": "sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", + "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^2.7.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/postcss-svgo/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/postcss-svgo/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + }, + "node_modules/postcss-svgo/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-svgo/node_modules/svgo": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", + "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/postprocessing": { + "version": "6.36.4", + "resolved": "https://registry.npmjs.org/postprocessing/-/postprocessing-6.36.4.tgz", + "integrity": "sha512-3fAyBGuLNR7Rg/q+f2SNlsVCI5mDrymvxhOif3tPKEej8M38z4TvwzNZm+RNpRY2tACE7qQUNE5IHyMcqgvlAg==", + "license": "Zlib", + "peerDependencies": { + "three": ">= 0.157.0 < 0.171.0" + } + }, + "node_modules/potpack": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz", + "integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/promise-worker-transferable": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/promise-worker-transferable/-/promise-worker-transferable-1.0.4.tgz", + "integrity": "sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw==", + "dependencies": { + "is-promise": "^2.1.0", + "lie": "^3.0.2" + } + }, + "node_modules/prompt-sync": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/prompt-sync/-/prompt-sync-4.2.0.tgz", + "integrity": "sha512-BuEzzc5zptP5LsgV5MZETjDaKSWfchl5U9Luiu8SKp7iZWD5tZalOxvNcZRwv+d2phNFr8xlbxmFNcRKfJOzJw==", + "dependencies": { + "strip-ansi": "^5.0.0" + } + }, + "node_modules/prompt-sync/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/prompt-sync/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", + "dev": true + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, + "node_modules/pump": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quickselect": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", + "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==" + }, + "node_modules/raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "dependencies": { + "performance-now": "^2.1.0" + } + }, + "node_modules/raf-schd": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz", + "integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==", + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rbush": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/rbush/-/rbush-3.0.1.tgz", + "integrity": "sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==", + "dependencies": { + "quickselect": "^2.0.0" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-app-polyfill": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz", + "integrity": "sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w==", + "dependencies": { + "core-js": "^3.19.2", + "object-assign": "^4.1.1", + "promise": "^8.1.0", + "raf": "^3.4.1", + "regenerator-runtime": "^0.13.9", + "whatwg-fetch": "^3.6.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/react-app-polyfill/node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "node_modules/react-beautiful-dnd": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/react-beautiful-dnd/-/react-beautiful-dnd-13.1.1.tgz", + "integrity": "sha512-0Lvs4tq2VcrEjEgDXHjT98r+63drkKEgqyxdA7qD3mvKwga6a5SscbdLPO2IExotU1jW8L0Ksdl0Cj2AF67nPQ==", + "deprecated": "react-beautiful-dnd is now deprecated. Context and options: https://github.com/atlassian/react-beautiful-dnd/issues/2672", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.9.2", + "css-box-model": "^1.2.0", + "memoize-one": "^5.1.1", + "raf-schd": "^4.0.2", + "react-redux": "^7.2.0", + "redux": "^4.0.4", + "use-memo-one": "^1.1.1" + }, + "peerDependencies": { + "react": "^16.8.5 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.5 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-colorful": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.6.1.tgz", + "integrity": "sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/react-composer": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/react-composer/-/react-composer-5.0.3.tgz", + "integrity": "sha512-1uWd07EME6XZvMfapwZmc7NgCZqDemcvicRi3wMJzXsQLvZ3L7fTHVyPy1bZdnWXM4iPjYuNE+uJ41MLKeTtnA==", + "dependencies": { + "prop-types": "^15.6.0" + }, + "peerDependencies": { + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-dev-utils": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", + "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", + "dependencies": { + "@babel/code-frame": "^7.16.0", + "address": "^1.1.2", + "browserslist": "^4.18.1", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "detect-port-alt": "^1.1.6", + "escape-string-regexp": "^4.0.0", + "filesize": "^8.0.6", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^6.5.0", + "global-modules": "^2.0.0", + "globby": "^11.0.4", + "gzip-size": "^6.0.0", + "immer": "^9.0.7", + "is-root": "^2.1.0", + "loader-utils": "^3.2.0", + "open": "^8.4.0", + "pkg-up": "^3.1.0", + "prompts": "^2.4.2", + "react-error-overlay": "^6.0.11", + "recursive-readdir": "^2.2.2", + "shell-quote": "^1.7.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/react-dev-utils/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/loader-utils": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/react-dev-utils/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-dom/node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/react-dropzone": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-12.1.0.tgz", + "integrity": "sha512-iBYHA1rbopIvtzokEX4QubO6qk5IF/x3BtKGu74rF2JkQDXnwC4uO/lHKpaw4PJIV6iIAYOlwLv2FpiGyqHNog==", + "license": "MIT", + "dependencies": { + "attr-accept": "^2.2.2", + "file-selector": "^0.5.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">= 10.13" + }, + "peerDependencies": { + "react": ">= 16.8" + } + }, + "node_modules/react-easy-sort": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/react-easy-sort/-/react-easy-sort-1.6.0.tgz", + "integrity": "sha512-zd9Nn90wVlZPEwJrpqElN87sf9GZnFR1StfjgNQVbSpR5QTSzCHjEYK6REuwq49Ip+76KOMSln9tg/ST2KLelg==", + "license": "MIT", + "dependencies": { + "array-move": "^3.0.1", + "tslib": "2.0.1" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "react": ">=16.4.0", + "react-dom": ">=16.4.0" + } + }, + "node_modules/react-easy-sort/node_modules/array-move": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/array-move/-/array-move-3.0.1.tgz", + "integrity": "sha512-H3Of6NIn2nNU1gsVDqDnYKY/LCdWvCMMOWifNGhKcVQgiZ6nOek39aESOvro6zmueP07exSl93YLvkN4fZOkSg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-easy-sort/node_modules/tslib": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.1.tgz", + "integrity": "sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==", + "license": "0BSD" + }, + "node_modules/react-error-overlay": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", + "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, + "node_modules/react-reconciler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.27.0.tgz", + "integrity": "sha512-HmMDKciQjYmBRGuuhIaKA1ba/7a+UsM5FzOZsMO2JYHt9Jh8reCb7j1eDC95NOyUlKM9KRyvdx0flBuDvYSBoA==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.21.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "react": "^18.0.0" + } + }, + "node_modules/react-redux": { + "version": "7.2.9", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz", + "integrity": "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.15.4", + "@types/react-redux": "^7.1.20", + "hoist-non-react-statics": "^3.3.2", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + }, + "peerDependencies": { + "react": "^16.8.3 || ^17 || ^18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/react-refresh": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", + "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.0.1.tgz", + "integrity": "sha512-WVAhv9oWCNsja5AkK6KLpXJDSJCQizOIyOd4vvB/+eHGbYx5vkhcmcmwWjQ9yqkRClogi+xjEg9fNEOd5EX/tw==", + "license": "MIT", + "dependencies": { + "@types/cookie": "^0.6.0", + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0", + "turbo-stream": "2.4.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.0.1.tgz", + "integrity": "sha512-duBzwAAiIabhFPZfDjcYpJ+f08TMbPMETgq254GWne2NW1ZwRHhZLj7tpSp8KGb7JvZzlLcjGUnqLxpZQVEPng==", + "license": "MIT", + "dependencies": { + "react-router": "7.0.1" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/react-router/node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/react-scripts": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", + "integrity": "sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.16.0", + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", + "@svgr/webpack": "^5.5.0", + "babel-jest": "^27.4.2", + "babel-loader": "^8.2.3", + "babel-plugin-named-asset-import": "^0.3.8", + "babel-preset-react-app": "^10.0.1", + "bfj": "^7.0.2", + "browserslist": "^4.18.1", + "camelcase": "^6.2.1", + "case-sensitive-paths-webpack-plugin": "^2.4.0", + "css-loader": "^6.5.1", + "css-minimizer-webpack-plugin": "^3.2.0", + "dotenv": "^10.0.0", + "dotenv-expand": "^5.1.0", + "eslint": "^8.3.0", + "eslint-config-react-app": "^7.0.1", + "eslint-webpack-plugin": "^3.1.1", + "file-loader": "^6.2.0", + "fs-extra": "^10.0.0", + "html-webpack-plugin": "^5.5.0", + "identity-obj-proxy": "^3.0.0", + "jest": "^27.4.3", + "jest-resolve": "^27.4.2", + "jest-watch-typeahead": "^1.0.0", + "mini-css-extract-plugin": "^2.4.5", + "postcss": "^8.4.4", + "postcss-flexbugs-fixes": "^5.0.2", + "postcss-loader": "^6.2.1", + "postcss-normalize": "^10.0.1", + "postcss-preset-env": "^7.0.1", + "prompts": "^2.4.2", + "react-app-polyfill": "^3.0.0", + "react-dev-utils": "^12.0.1", + "react-refresh": "^0.11.0", + "resolve": "^1.20.0", + "resolve-url-loader": "^4.0.0", + "sass-loader": "^12.3.0", + "semver": "^7.3.5", + "source-map-loader": "^3.0.0", + "style-loader": "^3.3.1", + "tailwindcss": "^3.0.2", + "terser-webpack-plugin": "^5.2.5", + "webpack": "^5.64.4", + "webpack-dev-server": "^4.6.0", + "webpack-manifest-plugin": "^4.0.2", + "workbox-webpack-plugin": "^6.4.1" + }, + "bin": { + "react-scripts": "bin/react-scripts.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + }, + "peerDependencies": { + "react": ">= 16", + "typescript": "^3.2.1 || ^4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/react-scripts/node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "engines": { + "node": ">=10" + } + }, + "node_modules/react-scripts/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/react-smooth": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz", + "integrity": "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==", + "license": "MIT", + "dependencies": { + "fast-equals": "^5.0.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-sortablejs": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/react-sortablejs/-/react-sortablejs-6.1.4.tgz", + "integrity": "sha512-fc7cBosfhnbh53Mbm6a45W+F735jwZ1UFIYSrIqcO/gRIFoDyZeMtgKlpV4DdyQfbCzdh5LoALLTDRxhMpTyXQ==", + "license": "MIT", + "dependencies": { + "classnames": "2.3.1", + "tiny-invariant": "1.2.0" + }, + "peerDependencies": { + "@types/sortablejs": "1", + "react": ">=16.9.0", + "react-dom": ">=16.9.0", + "sortablejs": "1" + } + }, + "node_modules/react-sortablejs/node_modules/tiny-invariant": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz", + "integrity": "sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==", + "license": "MIT" + }, + "node_modules/react-toastify": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.6.tgz", + "integrity": "sha512-yYjp+omCDf9lhZcrZHKbSq7YMuK0zcYkDFTzfRFgTXkTFHZ1ToxwAonzA4JI5CxA91JpjFLmwEsZEgfYfOqI1A==", + "dependencies": { + "clsx": "^2.1.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/recharts": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.1.tgz", + "integrity": "sha512-v8PUTUlyiDe56qUj82w/EDVuzEFXwEHp9/xOowGAZwfLjB9uAy3GllQVIYMWF6nU+qibx85WF75zD7AjqoT54Q==", + "license": "MIT", + "dependencies": { + "clsx": "^2.0.0", + "eventemitter3": "^4.0.1", + "lodash": "^4.17.21", + "react-is": "^18.3.1", + "react-smooth": "^4.0.4", + "recharts-scale": "^0.4.4", + "tiny-invariant": "^1.3.1", + "victory-vendor": "^36.6.8" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/recharts-scale": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", + "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", + "license": "MIT", + "dependencies": { + "decimal.js-light": "^2.4.1" + } + }, + "node_modules/recharts/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/recursive-readdir/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/recursive-readdir/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-parser": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.0.tgz", + "integrity": "sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg==" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", + "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.1.1.tgz", + "integrity": "sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw==", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.11.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==" + }, + "node_modules/regjsparser": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.11.2.tgz", + "integrity": "sha512-3OGZZ4HoLJkkAZx/48mTXJNlmqTGOzc0o9OWQPuWpkOlXXPbyN6OafCcoXUnBqE2D3f/T5L+pWc1kdEmnfnRsA==", + "dependencies": { + "jsesc": "~3.0.2" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/reinterval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", + "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==", + "license": "MIT" + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/request-progress": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", + "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", + "dev": true, + "dependencies": { + "throttleit": "^1.0.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-url-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz", + "integrity": "sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA==", + "dependencies": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^7.0.35", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=8.9" + }, + "peerDependencies": { + "rework": "1.0.1", + "rework-visit": "1.0.0" + }, + "peerDependenciesMeta": { + "rework": { + "optional": true + }, + "rework-visit": { + "optional": true + } + } + }, + "node_modules/resolve-url-loader/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/resolve-url-loader/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" + }, + "node_modules/resolve-url-loader/node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/resolve-url-loader/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve.exports": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", + "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==" + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/robust-predicates": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-2.0.4.tgz", + "integrity": "sha512-l4NwboJM74Ilm4VKfbAtFeGq7aEjWL+5kVFcmgFA2MrdnQWx9iE/tUGvxY5HyMI7o/WpSIUFLbC5fbeaHgSCYg==" + }, + "node_modules/rollup": { + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0" + } + }, + "node_modules/rollup-plugin-terser/node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/rollup-plugin-terser/node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sanitize.css": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz", + "integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==" + }, + "node_modules/sass": { + "version": "1.80.4", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.80.4.tgz", + "integrity": "sha512-rhMQ2tSF5CsuuspvC94nPM9rToiAFw2h3JTrLlgmNw1MH79v8Cr3DH6KF6o6r+8oofY3iYVPUf66KzC8yuVN1w==", + "dependencies": { + "@parcel/watcher": "^2.4.1", + "chokidar": "^4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-loader": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", + "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", + "dependencies": { + "klona": "^2.0.4", + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + } + } + }, + "node_modules/sass/node_modules/chokidar": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", + "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sass/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scheduler": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", + "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/schema-utils/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/schema-utils/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "license": "MIT" + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "node_modules/skmeans": { + "version": "0.9.7", + "resolved": "https://registry.npmjs.org/skmeans/-/skmeans-0.9.7.tgz", + "integrity": "sha512-hNj1/oZ7ygsfmPZ7ZfN5MUBRoGg1gtpnImuJBgLO0ljQ67DtJuiQaiYdS4lUA6s0KCwnPhGivtC/WRwIZLkHyg==" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/socket.io-client": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz", + "integrity": "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.6.1", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/sockjs/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/sortablejs": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.6.tgz", + "integrity": "sha512-aNfiuwMEpfBM/CN6LY0ibyhxPfPbyFeBTYJKCvzkJ2GkUpazIt3H+QIPAMHwqQ7tMKaHz1Qj+rJJCqljnf4p3A==", + "license": "MIT" + }, + "node_modules/source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.2.tgz", + "integrity": "sha512-BokxPoLjyl3iOrgkWaakaxqnelAJSS+0V+De0kKIq6lyWrXuiPgYTGp6z3iHmqljKAaLXwZa+ctD8GccRJeVvg==", + "dependencies": { + "abab": "^2.0.5", + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead" + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/splaytree": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/splaytree/-/splaytree-3.1.2.tgz", + "integrity": "sha512-4OM2BJgC5UzrhVnnJA4BkHKGtjXNzzUfpQjCO8I05xYPsfS/VuQDwjCGGMi8rYQilHEV4j8NBqTFbls/PZEE7A==" + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "license": "MIT", + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" + }, + "node_modules/static-eval": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", + "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", + "dependencies": { + "escodegen": "^1.8.1" + } + }, + "node_modules/static-eval/node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/static-eval/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/static-eval/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/static-eval/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/static-eval/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/static-eval/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-eval/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/stats-gl": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/stats-gl/-/stats-gl-2.2.8.tgz", + "integrity": "sha512-94G5nZvduDmzxBS7K0lYnynYwreZpkknD8g5dZmU6mpwIhy3caCrjAm11Qm1cbyx7mqix7Fp00RkbsonzKWnoQ==", + "dependencies": { + "@types/three": "^0.163.0" + } + }, + "node_modules/stats-gl/node_modules/@types/three": { + "version": "0.163.0", + "resolved": "https://registry.npmjs.org/@types/three/-/three-0.163.0.tgz", + "integrity": "sha512-uIdDhsXRpQiBUkflBS/i1l3JX14fW6Ot9csed60nfbZNXHDTRsnV2xnTVwXcgbvTiboAR4IW+t+lTL5f1rqIqA==", + "dependencies": { + "@tweenjs/tween.js": "~23.1.1", + "@types/stats.js": "*", + "@types/webxr": "*", + "fflate": "~0.8.2", + "meshoptimizer": "~0.18.1" + } + }, + "node_modules/stats.js": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/stats.js/-/stats.js-0.17.0.tgz", + "integrity": "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==" + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "dependencies": { + "internal-slot": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-natural-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", + "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/string.prototype.includes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "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" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-loader": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", + "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/stylehacks": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", + "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", + "dependencies": { + "browserslist": "^4.21.4", + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/sucrase/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + }, + "node_modules/sucrase/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/suspend-react": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/suspend-react/-/suspend-react-0.1.3.tgz", + "integrity": "sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==", + "peerDependencies": { + "react": ">=17.0" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" + }, + "node_modules/svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", + "dependencies": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/svgo/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/svgo/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/svgo/node_modules/css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "node_modules/svgo/node_modules/css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/svgo/node_modules/dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/svgo/node_modules/domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/svgo/node_modules/domutils/node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "node_modules/svgo/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/svgo/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sweepline-intersections": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sweepline-intersections/-/sweepline-intersections-1.5.0.tgz", + "integrity": "sha512-AoVmx72QHpKtItPu72TzFL+kcYjd67BPLDoR0LarIk+xyaRg+pDTMFXndIEvZf9xEKnJv6JdhgRMnocoG0D3AQ==", + "dependencies": { + "tinyqueue": "^2.0.0" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "node_modules/tailwindcss": { + "version": "3.4.14", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz", + "integrity": "sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.0", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/tempy": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", + "dependencies": { + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz", + "integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/three": { + "version": "0.168.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.168.0.tgz", + "integrity": "sha512-6m6jXtDwMJEK/GGMbAOTSAmxNdzKvvBzgd7q8bE/7Tr6m7PaBh5kKLrN7faWtlglXbzj7sVba48Idwx+NRsZXw==" + }, + "node_modules/three-bvh-csg": { + "version": "0.0.16", + "resolved": "https://registry.npmjs.org/three-bvh-csg/-/three-bvh-csg-0.0.16.tgz", + "integrity": "sha512-RgC5dY0hAKdfd1bmD3o2CDfmK9GTkvsA1ECzoqTMhSkjSc2zp1z4Wpa5+emLi/EosF5P6+aK2veTxTLZA9+Mhw==", + "peerDependencies": { + "three": ">=0.151.0", + "three-mesh-bvh": ">=0.6.6" + } + }, + "node_modules/three-mesh-bvh": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/three-mesh-bvh/-/three-mesh-bvh-0.6.8.tgz", + "integrity": "sha512-EGebF9DZx1S8+7OZYNNTT80GXJZVf+UYXD/HyTg/e2kR/ApofIFfUS4ZzIHNnUVIadpnLSzM4n96wX+l7GMbnQ==", + "peerDependencies": { + "three": ">= 0.151.0" + } + }, + "node_modules/three-stdlib": { + "version": "2.33.0", + "resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.33.0.tgz", + "integrity": "sha512-V/uycBuqQOP/3Z+FBtpMdj2Ds5PyfJ3VDfMzktEmG4niOIzv7q1y5uMSbMcng0+057m1l0N147FQxsodQo9zBg==", + "dependencies": { + "@types/draco3d": "^1.4.0", + "@types/offscreencanvas": "^2019.6.4", + "@types/webxr": "^0.5.2", + "draco3d": "^1.4.1", + "fflate": "^0.6.9", + "potpack": "^1.0.1" + }, + "peerDependencies": { + "three": ">=0.128.0" + } + }, + "node_modules/three-stdlib/node_modules/fflate": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz", + "integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==" + }, + "node_modules/throat": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", + "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==" + }, + "node_modules/throttleit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", + "integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, + "node_modules/tinyqueue": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz", + "integrity": "sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==" + }, + "node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/topojson-client": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.1.0.tgz", + "integrity": "sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==", + "dependencies": { + "commander": "2" + }, + "bin": { + "topo2geo": "bin/topo2geo", + "topomerge": "bin/topomerge", + "topoquantize": "bin/topoquantize" + } + }, + "node_modules/topojson-client/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/topojson-server": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/topojson-server/-/topojson-server-3.0.1.tgz", + "integrity": "sha512-/VS9j/ffKr2XAOjlZ9CgyyeLmgJ9dMwq6Y0YEON8O7p/tGGk+dCWnrE03zEdu7i4L7YsFZLEPZPzCvcB7lEEXw==", + "dependencies": { + "commander": "2" + }, + "bin": { + "geo2topo": "bin/geo2topo" + } + }, + "node_modules/topojson-server/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/troika-three-text": { + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/troika-three-text/-/troika-three-text-0.49.1.tgz", + "integrity": "sha512-lXGWxgjJP9kw4i4Wh+0k0Q/7cRfS6iOME4knKht/KozPu9GcFA9NnNpRvehIhrUawq9B0ZRw+0oiFHgRO+4Wig==", + "dependencies": { + "bidi-js": "^1.0.2", + "troika-three-utils": "^0.49.0", + "troika-worker-utils": "^0.49.0", + "webgl-sdf-generator": "1.1.1" + }, + "peerDependencies": { + "three": ">=0.125.0" + } + }, + "node_modules/troika-three-utils": { + "version": "0.49.0", + "resolved": "https://registry.npmjs.org/troika-three-utils/-/troika-three-utils-0.49.0.tgz", + "integrity": "sha512-umitFL4cT+Fm/uONmaQEq4oZlyRHWwVClaS6ZrdcueRvwc2w+cpNQ47LlJKJswpqtMFWbEhOLy0TekmcPZOdYA==", + "peerDependencies": { + "three": ">=0.125.0" + } + }, + "node_modules/troika-worker-utils": { + "version": "0.49.0", + "resolved": "https://registry.npmjs.org/troika-worker-utils/-/troika-worker-utils-0.49.0.tgz", + "integrity": "sha512-1xZHoJrG0HFfCvT/iyN41DvI/nRykiBtHqFkGaGgJwq5iXfIZFBiPPEHFpPpgyKM3Oo5ITHXP5wM2TNQszYdVg==" + }, + "node_modules/tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ts-node/node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", + "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tunnel-rat": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/tunnel-rat/-/tunnel-rat-0.1.2.tgz", + "integrity": "sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ==", + "dependencies": { + "zustand": "^4.3.2" + } + }, + "node_modules/tunnel-rat/node_modules/zustand": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.5.tgz", + "integrity": "sha512-+0PALYNJNgK6hldkgDq2vLrw5f6g/jCInz52n9RTpropGgeAf/ioFUCdtsjCqu4gNhW9D01rUQBROoRjdzyn2Q==", + "dependencies": { + "use-sync-external-store": "1.2.2" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } + }, + "node_modules/turbo-stream": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz", + "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==", + "license": "ISC" + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "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" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "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" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "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" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "license": "MIT" + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==" + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==" + }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/use-isomorphic-layout-effect": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.0.tgz", + "integrity": "sha512-q6ayo8DWoPZT0VdG4u3D3uxcgONP3Mevx2i2b0434cwWBoL+aelL1DzkXI6w3PhTZzUeR2kaVlZn70iCiseP6w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-memo-one": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.3.tgz", + "integrity": "sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/util.promisify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" + }, + "node_modules/utility-types": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", + "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/v8-to-istanbul": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/v8n": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/v8n/-/v8n-1.5.1.tgz", + "integrity": "sha512-LdabyT4OffkyXFCe9UT+uMkxNBs5rcTVuZClvxQr08D5TUgo1OFKkoT65qYRCsiKBl/usHjpXvP4hHMzzDRj3A==", + "license": "MIT" + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/victory-vendor": { + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", + "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==", + "license": "MIT AND ISC", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, + "node_modules/victory-vendor/node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/web-vitals": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz", + "integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg==" + }, + "node_modules/webgl-constants": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/webgl-constants/-/webgl-constants-1.1.1.tgz", + "integrity": "sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg==" + }, + "node_modules/webgl-sdf-generator": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/webgl-sdf-generator/-/webgl-sdf-generator-1.1.1.tgz", + "integrity": "sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA==" + }, + "node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "engines": { + "node": ">=10.4" + } + }, + "node_modules/webpack": { + "version": "5.95.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz", + "integrity": "sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==", + "dependencies": { + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", + "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-dev-server": { + "version": "4.15.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", + "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", + "dependencies": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.4", + "ws": "^8.13.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.37.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "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 + } + } + }, + "node_modules/webpack-manifest-plugin": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz", + "integrity": "sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow==", + "dependencies": { + "tapable": "^2.0.0", + "webpack-sources": "^2.2.0" + }, + "engines": { + "node": ">=12.22.0" + }, + "peerDependencies": { + "webpack": "^4.44.2 || ^5.47.0" + } + }, + "node_modules/webpack-manifest-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-manifest-plugin/node_modules/webpack-sources": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", + "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", + "dependencies": { + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==" + }, + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + }, + "node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", + "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", + "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" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "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" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workbox-background-sync": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.6.0.tgz", + "integrity": "sha512-jkf4ZdgOJxC9u2vztxLuPT/UjlH7m/nWRQ/MgGL0v8BJHoZdVGJd18Kck+a0e55wGXdqyHO+4IQTk0685g4MUw==", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-background-sync/node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "license": "ISC" + }, + "node_modules/workbox-broadcast-update": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.6.0.tgz", + "integrity": "sha512-nm+v6QmrIFaB/yokJmQ/93qIJ7n72NICxIwQwe5xsZiV2aI93MGGyEyzOzDPVz5THEr5rC3FJSsO3346cId64Q==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-build": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.6.0.tgz", + "integrity": "sha512-Tjf+gBwOTuGyZwMz2Nk/B13Fuyeo0Q84W++bebbVsfr9iLkDSo6j6PST8tET9HYA58mlRXwlMGpyWO8ETJiXdQ==", + "dependencies": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.11.1", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^11.2.1", + "@rollup/plugin-replace": "^2.4.1", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^9.0.1", + "glob": "^7.1.6", + "lodash": "^4.17.20", + "pretty-bytes": "^5.3.0", + "rollup": "^2.43.1", + "rollup-plugin-terser": "^7.0.0", + "source-map": "^0.8.0-beta.0", + "stringify-object": "^3.3.0", + "strip-comments": "^2.0.1", + "tempy": "^0.6.0", + "upath": "^1.2.0", + "workbox-background-sync": "6.6.0", + "workbox-broadcast-update": "6.6.0", + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-google-analytics": "6.6.0", + "workbox-navigation-preload": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-range-requests": "6.6.0", + "workbox-recipes": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0", + "workbox-streams": "6.6.0", + "workbox-sw": "6.6.0", + "workbox-window": "6.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", + "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", + "dependencies": { + "json-schema": "^0.4.0", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, + "node_modules/workbox-build/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/workbox-build/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/workbox-build/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/workbox-build/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/workbox-build/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/workbox-build/node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/workbox-build/node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/workbox-build/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "node_modules/workbox-build/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/workbox-cacheable-response": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.6.0.tgz", + "integrity": "sha512-JfhJUSQDwsF1Xv3EV1vWzSsCOZn4mQ38bWEBR3LdvOxSPgB65gAM6cS2CX8rkkKHRgiLrN7Wxoyu+TuH67kHrw==", + "deprecated": "workbox-background-sync@6.6.0", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-core": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.6.0.tgz", + "integrity": "sha512-GDtFRF7Yg3DD859PMbPAYPeJyg5gJYXuBQAC+wyrWuuXgpfoOrIQIvFRZnQ7+czTIQjIr1DhLEGFzZanAT/3bQ==" + }, + "node_modules/workbox-expiration": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.6.0.tgz", + "integrity": "sha512-baplYXcDHbe8vAo7GYvyAmlS4f6998Jff513L4XvlzAOxcl8F620O91guoJ5EOf5qeXG4cGdNZHkkVAPouFCpw==", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-expiration/node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "license": "ISC" + }, + "node_modules/workbox-google-analytics": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.6.0.tgz", + "integrity": "sha512-p4DJa6OldXWd6M9zRl0H6vB9lkrmqYFkRQ2xEiNdBFp9U0LhsGO7hsBscVEyH9H2/3eZZt8c97NB2FD9U2NJ+Q==", + "deprecated": "It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained", + "dependencies": { + "workbox-background-sync": "6.6.0", + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/workbox-navigation-preload": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.6.0.tgz", + "integrity": "sha512-utNEWG+uOfXdaZmvhshrh7KzhDu/1iMHyQOV6Aqup8Mm78D286ugu5k9MFD9SzBT5TcwgwSORVvInaXWbvKz9Q==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-precaching": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.6.0.tgz", + "integrity": "sha512-eYu/7MqtRZN1IDttl/UQcSZFkHP7dnvr/X3Vn6Iw6OsPMruQHiVjjomDFCNtd8k2RdjLs0xiz9nq+t3YVBcWPw==", + "dependencies": { + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/workbox-range-requests": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.6.0.tgz", + "integrity": "sha512-V3aICz5fLGq5DpSYEU8LxeXvsT//mRWzKrfBOIxzIdQnV/Wj7R+LyJVTczi4CQ4NwKhAaBVaSujI1cEjXW+hTw==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-recipes": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.6.0.tgz", + "integrity": "sha512-TFi3kTgYw73t5tg73yPVqQC8QQjxJSeqjXRO4ouE/CeypmP2O/xqmB/ZFBBQazLTPxILUQ0b8aeh0IuxVn9a6A==", + "dependencies": { + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/workbox-routing": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.6.0.tgz", + "integrity": "sha512-x8gdN7VDBiLC03izAZRfU+WKUXJnbqt6PG9Uh0XuPRzJPpZGLKce/FkOX95dWHRpOHWLEq8RXzjW0O+POSkKvw==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-strategies": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.6.0.tgz", + "integrity": "sha512-eC07XGuINAKUWDnZeIPdRdVja4JQtTuc35TZ8SwMb1ztjp7Ddq2CJ4yqLvWzFWGlYI7CG/YGqaETntTxBGdKgQ==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-streams": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.6.0.tgz", + "integrity": "sha512-rfMJLVvwuED09CnH1RnIep7L9+mj4ufkTyDPVaXPKlhi9+0czCu+SJggWCIFbPpJaAZmp2iyVGLqS3RUmY3fxg==", + "dependencies": { + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0" + } + }, + "node_modules/workbox-sw": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.6.0.tgz", + "integrity": "sha512-R2IkwDokbtHUE4Kus8pKO5+VkPHD2oqTgl+XJwh4zbF1HyjAbgNmK/FneZHVU7p03XUt9ICfuGDYISWG9qV/CQ==" + }, + "node_modules/workbox-webpack-plugin": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.6.0.tgz", + "integrity": "sha512-xNZIZHalboZU66Wa7x1YkjIqEy1gTR+zPM+kjrYJzqN7iurYZBctBLISyScjhkJKYuRrZUP0iqViZTh8rS0+3A==", + "dependencies": { + "fast-json-stable-stringify": "^2.1.0", + "pretty-bytes": "^5.4.1", + "upath": "^1.2.0", + "webpack-sources": "^1.4.3", + "workbox-build": "6.6.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "webpack": "^4.4.0 || ^5.9.0" + } + }, + "node_modules/workbox-webpack-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workbox-webpack-plugin/node_modules/webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dependencies": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "node_modules/workbox-window": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.6.0.tgz", + "integrity": "sha512-L4N9+vka17d16geaJXXRjENLFldvkWy7JyGxElRD0JvBxvFEd8LOhr+uXCcar/NzAmIBRv9EZ+M+Qr4mOoBITw==", + "dependencies": { + "@types/trusted-types": "^2.0.2", + "workbox-core": "6.6.0" + } + }, + "node_modules/worker-timers": { + "version": "7.1.8", + "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-7.1.8.tgz", + "integrity": "sha512-R54psRKYVLuzff7c1OTFcq/4Hue5Vlz4bFtNEIarpSiCYhpifHU3aIQI29S84o1j87ePCYqbmEJPqwBTf+3sfw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.24.5", + "tslib": "^2.6.2", + "worker-timers-broker": "^6.1.8", + "worker-timers-worker": "^7.0.71" + } + }, + "node_modules/worker-timers-broker": { + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-6.1.8.tgz", + "integrity": "sha512-FUCJu9jlK3A8WqLTKXM9E6kAmI/dR1vAJ8dHYLMisLNB/n3GuaFIjJ7pn16ZcD1zCOf7P6H62lWIEBi+yz/zQQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.24.5", + "fast-unique-numbers": "^8.0.13", + "tslib": "^2.6.2", + "worker-timers-worker": "^7.0.71" + } + }, + "node_modules/worker-timers-worker": { + "version": "7.0.71", + "resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-7.0.71.tgz", + "integrity": "sha512-ks/5YKwZsto1c2vmljroppOKCivB/ma97g9y77MAAz2TBBjPPgpoOiS1qYQKIgvGTr2QYPT3XhJWIB6Rj2MVPQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.24.5", + "tslib": "^2.6.2" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", + "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zustand": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.0.tgz", + "integrity": "sha512-LE+VcmbartOPM+auOjCCLQOsQ05zUTp8RkgwRzefUk+2jISdMMFnxvyTjA4YNWr5ZGXYbVsEMZosttuxUBkojQ==", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } + } + } +} diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000..bdf98e3 --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,77 @@ +{ + "name": "dwinzo-app", + "version": "0.1.0", + "private": true, + "dependencies": { + "@dnd-kit/core": "^6.3.1", + "@dnd-kit/sortable": "^10.0.0", + "@react-three/csg": "^3.2.0", + "@react-three/drei": "^9.113.0", + "@react-three/fiber": "^8.17.7", + "@react-three/postprocessing": "^2.16.3", + "@testing-library/jest-dom": "^5.17.0", + "@testing-library/react": "^13.4.0", + "@testing-library/user-event": "^13.5.0", + "@turf/turf": "^7.1.0", + "@types/jest": "^27.5.2", + "@types/react": "^18.3.5", + "@types/react-dom": "^18.3.0", + "@use-gesture/react": "^10.3.1", + "chart.js": "^4.4.8", + "glob": "^11.0.0", + "gsap": "^3.12.5", + "leva": "^0.10.0", + "mqtt": "^5.10.3", + "postprocessing": "^6.36.4", + "prompt-sync": "^4.2.0", + "react": "^18.3.1", + "react-beautiful-dnd": "^13.1.1", + "react-dom": "^18.3.1", + "react-easy-sort": "^1.6.0", + "react-router-dom": "^7.0.1", + "react-scripts": "5.0.1", + "react-sortablejs": "^6.1.4", + "react-toastify": "^10.0.5", + "recharts": "^2.15.1", + "sass": "^1.78.0", + "socket.io-client": "^4.8.1", + "sortablejs": "^1.15.6", + "three": "^0.168.0", + "typescript": "^4.9.5", + "uuid": "^11.1.0", + "web-vitals": "^2.1.4", + "zustand": "^5.0.0-rc.2" + }, + "scripts": { + "start": "react-scripts start", + "build": "GENERATE_SOURCEMAP=false react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject" + }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "devDependencies": { + "@types/node": "^22.9.1", + "@types/three": "^0.169.0", + "cypress": "^13.14.2", + "dotenv": "^16.4.5", + "husky": "^9.1.6", + "ts-node": "^10.9.2" + } +} diff --git a/frontend/public/favicon.ico b/frontend/public/favicon.ico new file mode 100644 index 0000000..a11777c Binary files /dev/null and b/frontend/public/favicon.ico differ diff --git a/frontend/public/index.html b/frontend/public/index.html new file mode 100644 index 0000000..de1c300 --- /dev/null +++ b/frontend/public/index.html @@ -0,0 +1,44 @@ + + + + + + + + + + + + + Dwinzo + + + +
+
+ + + diff --git a/frontend/public/logo192.png b/frontend/public/logo192.png new file mode 100644 index 0000000..fc44b0a Binary files /dev/null and b/frontend/public/logo192.png differ diff --git a/frontend/public/logo512.png b/frontend/public/logo512.png new file mode 100644 index 0000000..a4e47a6 Binary files /dev/null and b/frontend/public/logo512.png differ diff --git a/frontend/public/manifest.json b/frontend/public/manifest.json new file mode 100644 index 0000000..315b784 --- /dev/null +++ b/frontend/public/manifest.json @@ -0,0 +1,25 @@ +{ + "short_name": "Dwinzo", + "name": "Dwinzo - Your World Reimagined", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "logo192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/frontend/public/robots.txt b/frontend/public/robots.txt new file mode 100644 index 0000000..e9e57dc --- /dev/null +++ b/frontend/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/frontend/scripts/.gitignore b/frontend/scripts/.gitignore new file mode 100644 index 0000000..4c43fe6 --- /dev/null +++ b/frontend/scripts/.gitignore @@ -0,0 +1 @@ +*.js \ No newline at end of file diff --git a/frontend/scripts/git-prompt.ts b/frontend/scripts/git-prompt.ts new file mode 100644 index 0000000..abd2458 --- /dev/null +++ b/frontend/scripts/git-prompt.ts @@ -0,0 +1,74 @@ + +/*////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Git Pull Setup +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ + +import { execSync } from 'child_process'; +const prompt = require('prompt-sync')(); + +// Ask user whether to pull from Git +const pull_remote_repository: string = prompt('Do you want to pull from Git? (yes/no): '); + +if (pull_remote_repository.toLowerCase() === 'yes' || pull_remote_repository.toLowerCase() === 'y') { + console.log('Pulling latest changes from Git...'); + try { + execSync('git fetch', { stdio: 'inherit' }); // Execute git fetch + execSync('git pull', { stdio: 'inherit', timeout: 5000 }); // Execute git pull with timeout of 5s + console.log('Pull successful!'); + } catch (err: any) { + // If there's an error, log it and exit with an error code + if (err.signal === 'SIGTERM') { + console.error('Git pull timed out.'); + } else { + console.error('Error pulling from Git:', err); + } + process.exit(1); // Exit with non-zero code to signal failure + } +} else { + console.log('Skipping Git pull.'); +} + + +/*////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +husky initialization +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ + +import * as fs from "fs"; +import * as path from "path"; + +const source = path.join(__dirname, "..", ".husky", "pre-commit"); +const destinationDir = path.join(__dirname, "..", ".husky", "_"); +const destination = path.join(destinationDir, "pre-commit"); +console.log('source: ', source); +console.log('destination: ', destination); + +// Verify if the source file exists +if (!fs.existsSync(source)) { + console.error("Source file does not exist:", source); + process.exit(1); // Exit with an error code +} + +// Ensure the destination directory exists +if (!fs.existsSync(destinationDir)) { + fs.mkdirSync(destinationDir, { recursive: true }); +} + +// Read and write the content manually +fs.readFile(source, "utf-8", (readErr, data) => { + if (readErr) { + console.error("Failed to read source file:", readErr); + return; + } + else { + // console.log(`sourceData :`, data); + } + + fs.writeFile(destination, data.toString(), (writeErr) => { + if (writeErr) { + console.error("Failed to write to destination file:", writeErr); + } else { + // console.log('Data to be written in destination: ', data.toString()); + console.log("Successfully copied pre-commit hook to", destination); + } + }); +}); diff --git a/frontend/scripts/serve-docs.ts b/frontend/scripts/serve-docs.ts new file mode 100644 index 0000000..e69de29 diff --git a/frontend/scripts/validate-filenames.ts b/frontend/scripts/validate-filenames.ts new file mode 100644 index 0000000..824cd67 --- /dev/null +++ b/frontend/scripts/validate-filenames.ts @@ -0,0 +1,76 @@ +import * as glob from 'glob'; +import * as path from 'path'; +import * as fs from 'fs'; +const prompt = require('prompt-sync')(); + +// Function to check if a filename is in camelCase +function isCamelCase(filename: string): boolean { + const camelCasePattern = /^[a-z]+([A-Z][a-z]*)*$/; // Regular expression to match camelCase pattern + return camelCasePattern.test(filename); +} + +// Function to convert a filename to camelCase +function toCamelCase(filename: string): string { + return filename + .replace(/[_-]+(.)?/g, (_, chr) => (chr ? chr.toUpperCase() : '')) + .replace(/^[A-Z]/, (firstChar) => firstChar.toLowerCase()); // Ensure the first letter is lowercase +} + +// Function to get all non-camelCase filenames in the specified directory +function getNonCamelCaseFiles(directory: string): string[] { + const files = glob.sync(`${directory}/**/*.*`); // Get all files in the specified directory + return files.filter((filePath) => { + const filename = path.basename(filePath, path.extname(filePath)); // Get the filename without the extension + return !filename.startsWith('_') && !isCamelCase(filename); // Filter out files that start with '_' and non-camelCase files + }); +} + +// Function to prompt the user for renaming non-camelCase files or proceed automatically in non-interactive mode +function promptUserForRenaming(nonCamelCaseFiles: string[]): boolean { + if (process.stdout.isTTY) { + // If running interactively, prompt the user + const answer: string = prompt('Do you want to rename these files to camelCase? (yes/no): '); + return answer.toLowerCase() === 'yes' || answer.toLowerCase() === 'y'; + } else { + // If running in non-interactive mode, log default action and proceed without prompt + console.log("Running in non-interactive mode. Defaulting to renaming files."); + return true; + } +} + +// Function to rename files to camelCase +function renameFiles(nonCamelCaseFiles: string[]): void { + nonCamelCaseFiles.forEach((filePath) => { + const dir = path.dirname(filePath); // Get the directory path + const ext = path.extname(filePath); // Get the file extension + const oldFilename = path.basename(filePath, ext); // Get the filename without extension + const newFilename = toCamelCase(oldFilename) + ext; // Convert to camelCase and add back the extension + const newFilePath = path.join(dir, newFilename); // Generate the new file path + + try { + fs.renameSync(filePath, newFilePath); // Rename the file + console.log(`✅ Renamed: ${filePath} -> ${newFilePath}`); + } catch (error) { + console.error(`❌ Error renaming ${filePath}:`, error); + } + }); +} + +// Main function to execute the script +function main(): void { + const directory = 'src'; // Specify your target directory + const nonCamelCaseFiles = getNonCamelCaseFiles(directory); // Get non-camelCase files + + if (nonCamelCaseFiles.length > 0) { + console.error('❌ The following files are not in camelCase and do not start with an underscore:'); + nonCamelCaseFiles.forEach((file) => console.error(`- ${file}`)); + + // Prompt user for renaming in interactive mode or proceed automatically in non-interactive mode + renameFiles(nonCamelCaseFiles); + } else { + console.log('✅ All filenames are in camelCase or start with an underscore.'); + } +} + +// Execute the main function +main(); diff --git a/frontend/src/app.test.tsx b/frontend/src/app.test.tsx new file mode 100644 index 0000000..49e11a6 --- /dev/null +++ b/frontend/src/app.test.tsx @@ -0,0 +1,9 @@ +import React from "react"; +import { render, screen } from "@testing-library/react"; +import App from "./app"; + +test("renders learn react link", () => { + render(); + const linkElement = screen.getByText(/learn react/i); + expect(linkElement).toBeInTheDocument(); +}); diff --git a/frontend/src/app.tsx b/frontend/src/app.tsx new file mode 100644 index 0000000..468693b --- /dev/null +++ b/frontend/src/app.tsx @@ -0,0 +1,46 @@ +import "./assets/styles/main.scss"; +import ConformationPopup from "./components/templates/modals/conformationPopup"; +import { + BrowserRouter as Router, + Routes, + Route, + useLocation, +} from "react-router-dom"; + +import Project from "./pages/project/project"; +import SignInSignUp from "./pages/signin/signInUp"; +import { useEffect, useState } from "react"; + +import "./assets/styles/main.scss"; +import { ToastContainer } from "react-toastify"; + +function App() { + const [isSignIn, setIsSignIn] = useState(true); + + return ( +
+ + + + + } + /> + + } + /> + } /> + No such page} /> + + +
+ ); + +} + +export default App; diff --git a/frontend/src/assets/fonts/inter/inter18ptBlackItalic.ttf b/frontend/src/assets/fonts/inter/inter18ptBlackItalic.ttf new file mode 100644 index 0000000..b33602f Binary files /dev/null and b/frontend/src/assets/fonts/inter/inter18ptBlackItalic.ttf differ diff --git a/frontend/src/assets/fonts/inter/inter18ptBold.ttf b/frontend/src/assets/fonts/inter/inter18ptBold.ttf new file mode 100644 index 0000000..cd13f60 Binary files /dev/null and b/frontend/src/assets/fonts/inter/inter18ptBold.ttf differ diff --git a/frontend/src/assets/fonts/inter/inter18ptBoldItalic.ttf b/frontend/src/assets/fonts/inter/inter18ptBoldItalic.ttf new file mode 100644 index 0000000..0d19c1a Binary files /dev/null and b/frontend/src/assets/fonts/inter/inter18ptBoldItalic.ttf differ diff --git a/frontend/src/assets/fonts/inter/inter18ptExtraBold.ttf b/frontend/src/assets/fonts/inter/inter18ptExtraBold.ttf new file mode 100644 index 0000000..e71c601 Binary files /dev/null and b/frontend/src/assets/fonts/inter/inter18ptExtraBold.ttf differ diff --git a/frontend/src/assets/fonts/inter/inter18ptExtraBoldItalic.ttf b/frontend/src/assets/fonts/inter/inter18ptExtraBoldItalic.ttf new file mode 100644 index 0000000..df45062 Binary files /dev/null and b/frontend/src/assets/fonts/inter/inter18ptExtraBoldItalic.ttf differ diff --git a/frontend/src/assets/fonts/inter/inter18ptExtraLight.ttf b/frontend/src/assets/fonts/inter/inter18ptExtraLight.ttf new file mode 100644 index 0000000..f9c6cfc Binary files /dev/null and b/frontend/src/assets/fonts/inter/inter18ptExtraLight.ttf differ diff --git a/frontend/src/assets/fonts/inter/inter18ptExtraLightItalic.ttf b/frontend/src/assets/fonts/inter/inter18ptExtraLightItalic.ttf new file mode 100644 index 0000000..275f305 Binary files /dev/null and b/frontend/src/assets/fonts/inter/inter18ptExtraLightItalic.ttf differ diff --git a/frontend/src/assets/fonts/inter/inter18ptItalic.ttf b/frontend/src/assets/fonts/inter/inter18ptItalic.ttf new file mode 100644 index 0000000..14d3595 Binary files /dev/null and b/frontend/src/assets/fonts/inter/inter18ptItalic.ttf differ diff --git a/frontend/src/assets/fonts/inter/inter18ptLight.ttf b/frontend/src/assets/fonts/inter/inter18ptLight.ttf new file mode 100644 index 0000000..acae361 Binary files /dev/null and b/frontend/src/assets/fonts/inter/inter18ptLight.ttf differ diff --git a/frontend/src/assets/fonts/inter/inter18ptLightItalic.ttf b/frontend/src/assets/fonts/inter/inter18ptLightItalic.ttf new file mode 100644 index 0000000..f69e18b Binary files /dev/null and b/frontend/src/assets/fonts/inter/inter18ptLightItalic.ttf differ diff --git a/frontend/src/assets/fonts/inter/inter18ptMedium.ttf b/frontend/src/assets/fonts/inter/inter18ptMedium.ttf new file mode 100644 index 0000000..71d9017 Binary files /dev/null and b/frontend/src/assets/fonts/inter/inter18ptMedium.ttf differ diff --git a/frontend/src/assets/fonts/inter/inter18ptMediumItalic.ttf b/frontend/src/assets/fonts/inter/inter18ptMediumItalic.ttf new file mode 100644 index 0000000..5c8c8b1 Binary files /dev/null and b/frontend/src/assets/fonts/inter/inter18ptMediumItalic.ttf differ diff --git a/frontend/src/assets/fonts/inter/inter18ptRegular.ttf b/frontend/src/assets/fonts/inter/inter18ptRegular.ttf new file mode 100644 index 0000000..ce097c8 Binary files /dev/null and b/frontend/src/assets/fonts/inter/inter18ptRegular.ttf differ diff --git a/frontend/src/assets/fonts/inter/inter18ptSemiBold.ttf b/frontend/src/assets/fonts/inter/inter18ptSemiBold.ttf new file mode 100644 index 0000000..053185e Binary files /dev/null and b/frontend/src/assets/fonts/inter/inter18ptSemiBold.ttf differ diff --git a/frontend/src/assets/fonts/inter/inter18ptSemiBoldItalic.ttf b/frontend/src/assets/fonts/inter/inter18ptSemiBoldItalic.ttf new file mode 100644 index 0000000..d9c9896 Binary files /dev/null and b/frontend/src/assets/fonts/inter/inter18ptSemiBoldItalic.ttf differ diff --git a/frontend/src/assets/fonts/inter/inter18ptThin.ttf b/frontend/src/assets/fonts/inter/inter18ptThin.ttf new file mode 100644 index 0000000..e68ec47 Binary files /dev/null and b/frontend/src/assets/fonts/inter/inter18ptThin.ttf differ diff --git a/frontend/src/assets/fonts/inter/inter18ptThinItalic.ttf b/frontend/src/assets/fonts/inter/inter18ptThinItalic.ttf new file mode 100644 index 0000000..134e837 Binary files /dev/null and b/frontend/src/assets/fonts/inter/inter18ptThinItalic.ttf differ diff --git a/frontend/src/assets/fonts/poppins/poppinsBlack.ttf b/frontend/src/assets/fonts/poppins/poppinsBlack.ttf new file mode 100644 index 0000000..71c0f99 Binary files /dev/null and b/frontend/src/assets/fonts/poppins/poppinsBlack.ttf differ diff --git a/frontend/src/assets/fonts/poppins/poppinsBlackItalic.ttf b/frontend/src/assets/fonts/poppins/poppinsBlackItalic.ttf new file mode 100644 index 0000000..7aeb58b Binary files /dev/null and b/frontend/src/assets/fonts/poppins/poppinsBlackItalic.ttf differ diff --git a/frontend/src/assets/fonts/poppins/poppinsBold.ttf b/frontend/src/assets/fonts/poppins/poppinsBold.ttf new file mode 100644 index 0000000..00559ee Binary files /dev/null and b/frontend/src/assets/fonts/poppins/poppinsBold.ttf differ diff --git a/frontend/src/assets/fonts/poppins/poppinsBoldItalic.ttf b/frontend/src/assets/fonts/poppins/poppinsBoldItalic.ttf new file mode 100644 index 0000000..e61e8e8 Binary files /dev/null and b/frontend/src/assets/fonts/poppins/poppinsBoldItalic.ttf differ diff --git a/frontend/src/assets/fonts/poppins/poppinsExtraBold.ttf b/frontend/src/assets/fonts/poppins/poppinsExtraBold.ttf new file mode 100644 index 0000000..df70936 Binary files /dev/null and b/frontend/src/assets/fonts/poppins/poppinsExtraBold.ttf differ diff --git a/frontend/src/assets/fonts/poppins/poppinsExtraBoldItalic.ttf b/frontend/src/assets/fonts/poppins/poppinsExtraBoldItalic.ttf new file mode 100644 index 0000000..14d2b37 Binary files /dev/null and b/frontend/src/assets/fonts/poppins/poppinsExtraBoldItalic.ttf differ diff --git a/frontend/src/assets/fonts/poppins/poppinsExtraLight.ttf b/frontend/src/assets/fonts/poppins/poppinsExtraLight.ttf new file mode 100644 index 0000000..e76ec69 Binary files /dev/null and b/frontend/src/assets/fonts/poppins/poppinsExtraLight.ttf differ diff --git a/frontend/src/assets/fonts/poppins/poppinsExtraLightItalic.ttf b/frontend/src/assets/fonts/poppins/poppinsExtraLightItalic.ttf new file mode 100644 index 0000000..89513d9 Binary files /dev/null and b/frontend/src/assets/fonts/poppins/poppinsExtraLightItalic.ttf differ diff --git a/frontend/src/assets/fonts/poppins/poppinsItalic.ttf b/frontend/src/assets/fonts/poppins/poppinsItalic.ttf new file mode 100644 index 0000000..12b7b3c Binary files /dev/null and b/frontend/src/assets/fonts/poppins/poppinsItalic.ttf differ diff --git a/frontend/src/assets/fonts/poppins/poppinsLight.ttf b/frontend/src/assets/fonts/poppins/poppinsLight.ttf new file mode 100644 index 0000000..bc36bcc Binary files /dev/null and b/frontend/src/assets/fonts/poppins/poppinsLight.ttf differ diff --git a/frontend/src/assets/fonts/poppins/poppinsLightItalic.ttf b/frontend/src/assets/fonts/poppins/poppinsLightItalic.ttf new file mode 100644 index 0000000..9e70be6 Binary files /dev/null and b/frontend/src/assets/fonts/poppins/poppinsLightItalic.ttf differ diff --git a/frontend/src/assets/fonts/poppins/poppinsMedium.ttf b/frontend/src/assets/fonts/poppins/poppinsMedium.ttf new file mode 100644 index 0000000..6bcdcc2 Binary files /dev/null and b/frontend/src/assets/fonts/poppins/poppinsMedium.ttf differ diff --git a/frontend/src/assets/fonts/poppins/poppinsMediumItalic.ttf b/frontend/src/assets/fonts/poppins/poppinsMediumItalic.ttf new file mode 100644 index 0000000..be67410 Binary files /dev/null and b/frontend/src/assets/fonts/poppins/poppinsMediumItalic.ttf differ diff --git a/frontend/src/assets/fonts/poppins/poppinsRegular.ttf b/frontend/src/assets/fonts/poppins/poppinsRegular.ttf new file mode 100644 index 0000000..9f0c71b Binary files /dev/null and b/frontend/src/assets/fonts/poppins/poppinsRegular.ttf differ diff --git a/frontend/src/assets/fonts/poppins/poppinsSemiBold.ttf b/frontend/src/assets/fonts/poppins/poppinsSemiBold.ttf new file mode 100644 index 0000000..74c726e Binary files /dev/null and b/frontend/src/assets/fonts/poppins/poppinsSemiBold.ttf differ diff --git a/frontend/src/assets/fonts/poppins/poppinsSemiBoldItalic.ttf b/frontend/src/assets/fonts/poppins/poppinsSemiBoldItalic.ttf new file mode 100644 index 0000000..3e6c942 Binary files /dev/null and b/frontend/src/assets/fonts/poppins/poppinsSemiBoldItalic.ttf differ diff --git a/frontend/src/assets/fonts/poppins/poppinsThin.ttf b/frontend/src/assets/fonts/poppins/poppinsThin.ttf new file mode 100644 index 0000000..03e7366 Binary files /dev/null and b/frontend/src/assets/fonts/poppins/poppinsThin.ttf differ diff --git a/frontend/src/assets/fonts/poppins/poppinsThinItalic.ttf b/frontend/src/assets/fonts/poppins/poppinsThinItalic.ttf new file mode 100644 index 0000000..e26db5d Binary files /dev/null and b/frontend/src/assets/fonts/poppins/poppinsThinItalic.ttf differ diff --git a/frontend/src/assets/fonts/roboto/robotoBlack.ttf b/frontend/src/assets/fonts/roboto/robotoBlack.ttf new file mode 100644 index 0000000..58fa175 Binary files /dev/null and b/frontend/src/assets/fonts/roboto/robotoBlack.ttf differ diff --git a/frontend/src/assets/fonts/roboto/robotoBlackItalic.ttf b/frontend/src/assets/fonts/roboto/robotoBlackItalic.ttf new file mode 100644 index 0000000..0a4dfd0 Binary files /dev/null and b/frontend/src/assets/fonts/roboto/robotoBlackItalic.ttf differ diff --git a/frontend/src/assets/fonts/roboto/robotoBold.ttf b/frontend/src/assets/fonts/roboto/robotoBold.ttf new file mode 100644 index 0000000..e64db79 Binary files /dev/null and b/frontend/src/assets/fonts/roboto/robotoBold.ttf differ diff --git a/frontend/src/assets/fonts/roboto/robotoBoldItalic.ttf b/frontend/src/assets/fonts/roboto/robotoBoldItalic.ttf new file mode 100644 index 0000000..5e39ae9 Binary files /dev/null and b/frontend/src/assets/fonts/roboto/robotoBoldItalic.ttf differ diff --git a/frontend/src/assets/fonts/roboto/robotoItalic.ttf b/frontend/src/assets/fonts/roboto/robotoItalic.ttf new file mode 100644 index 0000000..65498ee Binary files /dev/null and b/frontend/src/assets/fonts/roboto/robotoItalic.ttf differ diff --git a/frontend/src/assets/fonts/roboto/robotoLight.ttf b/frontend/src/assets/fonts/roboto/robotoLight.ttf new file mode 100644 index 0000000..a7e0284 Binary files /dev/null and b/frontend/src/assets/fonts/roboto/robotoLight.ttf differ diff --git a/frontend/src/assets/fonts/roboto/robotoLightItalic.ttf b/frontend/src/assets/fonts/roboto/robotoLightItalic.ttf new file mode 100644 index 0000000..867b76d Binary files /dev/null and b/frontend/src/assets/fonts/roboto/robotoLightItalic.ttf differ diff --git a/frontend/src/assets/fonts/roboto/robotoMedium.ttf b/frontend/src/assets/fonts/roboto/robotoMedium.ttf new file mode 100644 index 0000000..0707e15 Binary files /dev/null and b/frontend/src/assets/fonts/roboto/robotoMedium.ttf differ diff --git a/frontend/src/assets/fonts/roboto/robotoMediumItalic.ttf b/frontend/src/assets/fonts/roboto/robotoMediumItalic.ttf new file mode 100644 index 0000000..4e3bf0d Binary files /dev/null and b/frontend/src/assets/fonts/roboto/robotoMediumItalic.ttf differ diff --git a/frontend/src/assets/fonts/roboto/robotoRegular.ttf b/frontend/src/assets/fonts/roboto/robotoRegular.ttf new file mode 100644 index 0000000..2d116d9 Binary files /dev/null and b/frontend/src/assets/fonts/roboto/robotoRegular.ttf differ diff --git a/frontend/src/assets/fonts/roboto/robotoThin.ttf b/frontend/src/assets/fonts/roboto/robotoThin.ttf new file mode 100644 index 0000000..ab68508 Binary files /dev/null and b/frontend/src/assets/fonts/roboto/robotoThin.ttf differ diff --git a/frontend/src/assets/fonts/roboto/robotoThinItalic.ttf b/frontend/src/assets/fonts/roboto/robotoThinItalic.ttf new file mode 100644 index 0000000..b2c3933 Binary files /dev/null and b/frontend/src/assets/fonts/roboto/robotoThinItalic.ttf differ diff --git a/frontend/src/assets/images/3dVector3.png b/frontend/src/assets/images/3dVector3.png new file mode 100644 index 0000000..0c05773 Binary files /dev/null and b/frontend/src/assets/images/3dVector3.png differ diff --git a/frontend/src/assets/images/svgExports.tsx b/frontend/src/assets/images/svgExports.tsx new file mode 100644 index 0000000..78ba16a --- /dev/null +++ b/frontend/src/assets/images/svgExports.tsx @@ -0,0 +1,1476 @@ +export function MenuBarIcon() { + return ( + + + + + + ); +} + +export function SwitchAppIcon() { + return ( + + + + + + + + + + + + ); +} + +export function SettingsIcon() { + return ( + + + + + ); +} + +export function SearchIcon() { + return ( + + + + ); +} + +export function DropDownIcon() { + return ( + + + + ); +} + +export function CursorIcon({ isActive }: { isActive: boolean }) { + return ( + + + + ); +} + +export function ScaleIcon({ isActive }: { isActive: boolean }) { + return ( + + + + + ); +} + +export function RotateIcon({ isActive }: { isActive: boolean }) { + return ( + + + + + + + + + + + + + + ); +} + +export function MoveIcon({ isActive }: { isActive: boolean }) { + return ( + + + + ); +} + +export function DrawWallIcon({ isActive }: { isActive: boolean }) { + return ( + + + + ); +} + +export function DrawZoneIcon({ isActive }: { isActive: boolean }) { + return ( + + + + + + ); +} + +export function DrawAsileIcon({ isActive }: { isActive: boolean }) { + return ( + + + + ); +} + +export function AddPillerIcon({ isActive }: { isActive: boolean }) { + return ( + + + + + + + + + ); +} + +export function DrawOnlyFloorIcon({ isActive }: { isActive: boolean }) { + return ( + + + + + + + + + + + ); +} + +export function DeleteToolIcon({ isActive }: { isActive: boolean }) { + return ( + + + + + + + + ); +} + +export function UndoRight() { + return ( + + + + + ); +} + +export function UndoLeft() { + return ( + + + + + ); +} + +export function UploadIcon() { + return ( + + + + + ); +} + +export function EyeIcon() { + return ( + + + + + ); +} + +export function LockIcon() { + return ( + + + + ); +} + +export function ChairIcon() { + return ( + + + + + ); +} + +export function WallIcon() { + return ( + + + + + + + + + + ); +} + +export function FilterIcon() { + return ( + + + + + + + + + ); +} + +export function LeftClickIcon() { + return ( + + + + + ); +} + +export function RightClickIcon() { + return ( + + + + + ); +} + +export function CenterClickIcon() { + return ( + + + + ); +} + +export function DeleteIcon() { + return ( + + + + ); +} + +export function FreeIcon() { + return ( + + + + ); +} + +export function FlipIcon() { + return ( + + + + + + + + + + + ); +} + +export function FlipIcon2() { + return ( + + + + + + + + + + + ); +} + +export function FlipIcon3() { + return ( + + + + + + + + + + + ); +} + +export function FocusIcon() { + return ( + + + + + + + + + ); +} + +export function RecFocusIcon() { + return ( + + + + + ); +} + +export function RenameIcon() { + return ( + + + + + + ); +} + +export function SetOrginIcon() { + return ( + + + + + + + ); +} + +export function GroupIcon() { + return ( + + + + + + ); +} + +export function CloseIcon({ fill }: { fill: string }) { + return ( + + + + ); +} + +export function ObjectIcon({ isActive }: { isActive: boolean }) { + return ( + + + + ); +} + +export function WorldIcon({ isActive }: { isActive: boolean }) { + return ( + + + + + + ); +} + +export function MaterialIcon({ isActive }: { isActive: boolean }) { + return ( + + + + + + + + + + + + + + + + + + + + + + + + ); +} + +export function StarIcon({ fill }: { fill: string }) { + return ( + + + + ); +} + +// export function CloseIcon({ fill }: { fill: string }) { +// return ( +// +// +// +// ); +// } + +export function FillDropDown() { + return ( + + + + ); +} +export function FillDropUp() { + return ( + + + + ); +} + +export function MesureIcon({ isActive }: { isActive: boolean }) { + return ( + + + + + + + + + + + ); +} + +export function ThemeIcon() { + return ( + + + + + ); +} + +export function LinkIcon() { + return ( + + + + ); +} + +export function DisableSorting() { + return ( + + + + + ); +} + +export function CleanPannel() { + return ( + + + + + + + + + + + + + + + + + ); +} + +export function RemoveIcon() { + return ( + + + + ); +} diff --git a/frontend/src/assets/images/tempimages/asset1.png b/frontend/src/assets/images/tempimages/asset1.png new file mode 100644 index 0000000..615ebfa Binary files /dev/null and b/frontend/src/assets/images/tempimages/asset1.png differ diff --git a/frontend/src/assets/images/tempimages/asset2.png b/frontend/src/assets/images/tempimages/asset2.png new file mode 100644 index 0000000..188665a Binary files /dev/null and b/frontend/src/assets/images/tempimages/asset2.png differ diff --git a/frontend/src/assets/images/tempimages/asset3.png b/frontend/src/assets/images/tempimages/asset3.png new file mode 100644 index 0000000..a44216e Binary files /dev/null and b/frontend/src/assets/images/tempimages/asset3.png differ diff --git a/frontend/src/assets/images/tempimages/asset4.png b/frontend/src/assets/images/tempimages/asset4.png new file mode 100644 index 0000000..92c99bd Binary files /dev/null and b/frontend/src/assets/images/tempimages/asset4.png differ diff --git a/frontend/src/assets/images/tempimages/asset5.png b/frontend/src/assets/images/tempimages/asset5.png new file mode 100644 index 0000000..463b1d6 Binary files /dev/null and b/frontend/src/assets/images/tempimages/asset5.png differ diff --git a/frontend/src/assets/images/tempimages/asset6.png b/frontend/src/assets/images/tempimages/asset6.png new file mode 100644 index 0000000..17ff5ae Binary files /dev/null and b/frontend/src/assets/images/tempimages/asset6.png differ diff --git a/frontend/src/assets/images/tempimages/asset7.png b/frontend/src/assets/images/tempimages/asset7.png new file mode 100644 index 0000000..d8dba41 Binary files /dev/null and b/frontend/src/assets/images/tempimages/asset7.png differ diff --git a/frontend/src/assets/images/tempimages/asset8.png b/frontend/src/assets/images/tempimages/asset8.png new file mode 100644 index 0000000..1b4f669 Binary files /dev/null and b/frontend/src/assets/images/tempimages/asset8.png differ diff --git a/frontend/src/assets/images/tempimages/asset9.png b/frontend/src/assets/images/tempimages/asset9.png new file mode 100644 index 0000000..c8e9b47 Binary files /dev/null and b/frontend/src/assets/images/tempimages/asset9.png differ diff --git a/frontend/src/assets/images/tempimages/customCurser.png b/frontend/src/assets/images/tempimages/customCurser.png new file mode 100644 index 0000000..02cf32c Binary files /dev/null and b/frontend/src/assets/images/tempimages/customCurser.png differ diff --git a/frontend/src/assets/images/userImage.png b/frontend/src/assets/images/userImage.png new file mode 100644 index 0000000..51af26c Binary files /dev/null and b/frontend/src/assets/images/userImage.png differ diff --git a/frontend/src/assets/models/gltf-glb/arch.glb b/frontend/src/assets/models/gltf-glb/arch.glb new file mode 100644 index 0000000..52f44ef Binary files /dev/null and b/frontend/src/assets/models/gltf-glb/arch.glb differ diff --git a/frontend/src/assets/models/gltf-glb/beanBag.glb b/frontend/src/assets/models/gltf-glb/beanBag.glb new file mode 100644 index 0000000..c84c112 Binary files /dev/null and b/frontend/src/assets/models/gltf-glb/beanBag.glb differ diff --git a/frontend/src/assets/models/gltf-glb/camera face 2.gltf b/frontend/src/assets/models/gltf-glb/camera face 2.gltf new file mode 100644 index 0000000..e1c418f --- /dev/null +++ b/frontend/src/assets/models/gltf-glb/camera face 2.gltf @@ -0,0 +1,121 @@ +{ + "asset":{ + "generator":"Khronos glTF Blender I/O v3.6.28", + "version":"2.0" + }, + "scene":0, + "scenes":[ + { + "name":"Scene", + "nodes":[ + 0 + ] + } + ], + "nodes":[ + { + "mesh":0, + "name":"Circle" + } + ], + "materials":[ + { + "doubleSided":true, + "name":"Material", + "pbrMetallicRoughness":{ + "baseColorFactor":[ + 0.011087078601121902, + 0.011087078601121902, + 0.011087078601121902, + 1 + ], + "metallicFactor":0, + "roughnessFactor":0.4000000059604645 + } + } + ], + "meshes":[ + { + "name":"Circle", + "primitives":[ + { + "attributes":{ + "POSITION":0, + "NORMAL":1, + "TEXCOORD_0":2 + }, + "indices":3, + "material":0 + } + ] + } + ], + "accessors":[ + { + "bufferView":0, + "componentType":5126, + "count":1910, + "max":[ + 0.29999983310699463, + 0.30012279748916626, + 0.6709707379341125 + ], + "min":[ + -0.30000022053718567, + -0.2998772859573364, + -0.3290294408798218 + ], + "type":"VEC3" + }, + { + "bufferView":1, + "componentType":5126, + "count":1910, + "type":"VEC3" + }, + { + "bufferView":2, + "componentType":5126, + "count":1910, + "type":"VEC2" + }, + { + "bufferView":3, + "componentType":5123, + "count":6084, + "type":"SCALAR" + } + ], + "bufferViews":[ + { + "buffer":0, + "byteLength":22920, + "byteOffset":0, + "target":34962 + }, + { + "buffer":0, + "byteLength":22920, + "byteOffset":22920, + "target":34962 + }, + { + "buffer":0, + "byteLength":15280, + "byteOffset":45840, + "target":34962 + }, + { + "buffer":0, + "byteLength":12168, + "byteOffset":61120, + "target":34963 + } + ], + "buffers":[ + { + "byteLength":73288, + "uri":"data:application/octet-stream;base64,FuMevm7hb7u9xCs/FuMevm7hb7u9xCs/N04cvsyIsDy9xCs/N04cvsyIsDy9xCs/AakUvgGPOz29xCs/AakUvgGPOz29xCs/rz4IvnmIiz29xCs/rz4IvnmIiz29xCs/wRLvvfmisz29xCs/wRLvvfmisz29xCs/6lrGvXuM1D29xCs/6lrGvXuM1D29xCs/c+aXvTUB7T27xCs/c+aXvTUB7T27xCs/vfxKvYcQ/D26xCs/vfxKvYcQ/D26xCs/VUrEvCeTAD66xCs/VUrEvCeTAD66xCs/R03WOocQ/D26xCs/R03WOocQ/D26xCs/HwXXPDEB7T26xCs/HwXXPDEB7T26xCs/f2tIPXiM1D26xCs/f2tIPXiM1D26xCs/ke2MPfSisz26xCs/ke2MPfSisz26xCs/LliuPXSIiz25xCs/LliuPXSIiz25xCs/1izHPfWOOz23xCs/1izHPfWOOz23xCs/P3fWPbKIsDy3xCs/P3fWPbKIsDy3xCs/+6DbPUbib7u3xCs/+6DbPUbib7u3xCs/PHfWPUKB7Ly3xCs/PHfWPUKB7Ly3xCs/1CzHPUeLWb23xCs/1CzHPUeLWb23xCs/KliuPZmGmr25xCs/KliuPZmGmr25xCs/jO2MPRyhwr26xCs/jO2MPRyhwr26xCs/dGtIPZmK4726xCs/dGtIPZmK4726xCs/BgXXPFT/+726xCs/BgXXPFT/+726xCs/mkvWOlSHBb66xCs/mkvWOlSHBb66xCs/cErEvDcSCL66xCs/cErEvDcSCL66xCs/y/xKvVKHBb66xCs/y/xKvVKHBb66xCs/euaXvVH/+727xCs/euaXvVH/+727xCs/8VrGvZaK4729xCs/8VrGvZaK4729xCs/xRLvvRehwr29xCs/xRLvvRehwr29xCs/sT4IvpOGmr29xCs/sT4IvpOGmr29xCs/BKkUvjqLWb29xCs/BKkUvjqLWb29xCs/N04cviiB7Ly9xCs/N04cviiB7Ly9xCs/Y3Itvk9myzzDPig/Y3Itvk9myzzDPig/OV0wvmHhb7vDPig/OV0wvmHhb7vDPig/k84kvmLoVT3DPig/k84kvmLoVT3DPig/y8YWvtmonj3DPig/y8YWvtmonj3DPig/EeUDvtn6yz3DPig/EeUDvtn6yz3DPig/T8bZvWMs8T3DPig/T8bZvWMs8T3DPig/z0alvcNnBj7BPig/z0alvcNnBj7BPig/NKBYvTPqDj7APig/NKBYvTPqDj7APig/WkrEvMLJET7APig/WkrEvMLJET7APig/u66iOzHqDj7APig/u66iOzHqDj7APig/QUMGPcJnBj7APig/QUMGPcJnBj7APig/QEJvPV4s8T3APig/QEJvPV4s8T3APig/86SlPdX6yz2/Pig/86SlPdX6yz2/Pig/ZmjLPdOonj29Pig/ZmjLPdOonj29Pig/9XfnPVPoVT29Pig/9XfnPVPoVT29Pig/j7/4PTBmyzy9Pig/j7/4PTBmyzy9Pig/PpX+PVXib7u9Pig/PpX+PVXib7u9Pig/jr/4PWKvA729Pig/jr/4PWKvA729Pig/8nfnPZ7kc729Pig/8nfnPZ7kc729Pig/YWjLPfemrb29Pig/YWjLPfemrb29Pig/7aSlPf342r2/Pig/7aSlPf342r2/Pig/M0JvPUIVAL7APig/M0JvPUIVAL7APig/MkMGPdXmDb7APig/MkMGPdXmDb7APig/Qq6iO0JpFr7APig/Qq6iO0JpFr7APig/eUrEvNJIGb7APig/eUrEvNJIGb7APig/QqBYvUFpFr7APig/QqBYvUFpFr7APig/1kalvdPmDb7BPig/1kalvdPmDb7BPig/VcbZvUEVAL7DPig/VcbZvUEVAL7DPig/FOUDvvj42r3DPig/FOUDvvj42r3DPig/zcYWvvGmrb3DPig/zcYWvvGmrb3DPig/lc4kvo/kc73DPig/lc4kvo/kc73DPig/Y3ItvlOvA73DPig/Y3ItvlOvA73DPig/aHItvk9myzyUhBI/aHItvk9myzyUhBI/PV0wvmHhb7uUhBI/PV0wvmHhb7uUhBI/l84kvmLoVT2UhBI/l84kvmLoVT2UhBI/z8YWvtmonj2UhBI/z8YWvtmonj2UhBI/FuUDvtn6yz2UhBI/FuUDvtn6yz2UhBI/XcbZvWMs8T2UhBI/XcbZvWMs8T2UhBI/20alvcNnBj6ShBI/20alvcNnBj6ShBI/S6BYvTPqDj6ShBI/S6BYvTPqDj6ShBI/jErEvMLJET6ShBI/jErEvMLJET6ShBI/9a2iOzHqDj6ShBI/9a2iOzHqDj6ShBI/KEMGPcJnBj6ShBI/KEMGPcJnBj6ShBI/KEJvPV4s8T2ShBI/KEJvPV4s8T2ShBI/5qSlPdX6yz2RhBI/5qSlPdX6yz2RhBI/V2jLPdOonj2PhBI/V2jLPdOonj2PhBI/53fnPVPoVT2PhBI/53fnPVPoVT2PhBI/gb/4PTBmyzyPhBI/gb/4PTBmyzyPhBI/MJX+PVXib7uPhBI/MJX+PVXib7uPhBI/f7/4PWKvA72PhBI/f7/4PWKvA72PhBI/43fnPZ7kc72PhBI/43fnPZ7kc72PhBI/U2jLPfemrb2PhBI/U2jLPfemrb2PhBI/4KSlPf342r2RhBI/4KSlPf342r2RhBI/HEJvPUIVAL6ShBI/HEJvPUIVAL6ShBI/GkMGPdXmDb6ShBI/GkMGPdXmDb6ShBI/fK2iO0JpFr6ShBI/fK2iO0JpFr6ShBI/q0rEvNJIGb6ShBI/q0rEvNJIGb6ShBI/WaBYvUFpFr6ShBI/WaBYvUFpFr6ShBI/40alvdPmDb6ShBI/40alvdPmDb6ShBI/ZMbZvUEVAL6UhBI/ZMbZvUEVAL6UhBI/GeUDvvj42r2UhBI/GeUDvvj42r2UhBI/0cYWvvGmrb2UhBI/0cYWvvGmrb2UhBI/ms4kvo/kc72UhBI/ms4kvo/kc72UhBI/aHItvlOvA72UhBI/aHItvlOvA72UhBI/NmtDvvHV7TwY7As/NmtDvvHV7TwY7As/QMRGvk7hb7sY7As/QMRGvk7hb7sY7As/DYE5vpuudz0Y7As/DYE5vpuudz0Y7As/TGcpvgwttz0Y7As/TGcpvgwttz0Y7As/WrwTvvwu6z0Y7As/WrwTvvwu6z0Y7As/xaryvbXuCj4Y7As/xaryvbXuCj4Y7As/PWy2vUHKGj4W7As/PWy2vUHKGj4W7As/rhtqvRuOJD4V7As/rhtqvRuOJD4V7As/lkrEvDLaJz4V7As/lkrEvDLaJz4V7As/YEQXPBuOJD4V7As/YEQXPBuOJD4V7As/540oPT7KGj4V7As/540oPT7KGj4V7As/dIWQPbLuCj4V7As/dIWQPbLuCj4V7As/ZVPFPfUu6z0T7As/ZVPFPfUu6z0T7As/SKnwPQUttz0T7As/SKnwPQUttz0T7As/Zm4IPoqudz0T7As/Zm4IPoqudz0T7As/jFgSPtDV7TwT7As/jFgSPtDV7TwT7As/lbEVPmbib7sT7As/lbEVPmbib7sT7As/jFgSPjTnFL0T7As/jFgSPjTnFL0T7As/Y24IPm/Vir0T7As/Y24IPm/Vir0T7As/Q6nwPSsrxr0T7As/Q6nwPSsrxr0T7As/X1PFPRYt+r0T7As/X1PFPRYt+r0T7As/bYWQPcVtEr4V7As/bYWQPcVtEr4V7As/1o0oPVFJIr4V7As/1o0oPVFJIr4V7As/G0QXPCkNLL4V7As/G0QXPCkNLL4V7As/ukrEvEJZL74V7As/ukrEvEJZL74V7As/vhtqvSgNLL4V7As/vhtqvSgNLL4V7As/Rmy2vU5JIr4W7As/Rmy2vU5JIr4W7As/zaryvcJtEr4Y7As/zaryvcJtEr4Y7As/XrwTvhAt+r0Y7As/XrwTvhAt+r0Y7As/TmcpviQrxr0Y7As/TmcpviQrxr0Y7As/EIE5vmfVir0Y7As/EIE5vmfVir0Y7As/NmtDviLnFL0Y7As/NmtDviLnFL0Y7As/RGtDvvHV7TwTf8M+RGtDvvHV7TwTf8M+TMRGvk7hb7sTf8M+TMRGvk7hb7sTf8M+GoE5vqyudz0Tf8M+GoE5vqyudz0Tf8M+WGcpvgwttz0Tf8M+WGcpvgwttz0Tf8M+aLwTvvwu6z0Tf8M+aLwTvvwu6z0Tf8M+3aryvbXuCj4Rf8M+3aryvbXuCj4Rf8M+VWy2vUHKGj4Rf8M+VWy2vUHKGj4Rf8M+3xtqvRuOJD4Pf8M+3xtqvRuOJD4Pf8M+9UrEvDLaJz4Nf8M+9UrEvDLaJz4Nf8M+okMXPBuOJD4Nf8M+okMXPBuOJD4Nf8M+t40oPT7KGj4Nf8M+t40oPT7KGj4Nf8M+W4WQPbLuCj4Lf8M+W4WQPbLuCj4Lf8M+TVPFPfUu6z0Kf8M+TVPFPfUu6z0Kf8M+L6nwPQUttz0Kf8M+L6nwPQUttz0Kf8M+WG4IPpuudz0Kf8M+WG4IPpuudz0Kf8M+gFgSPtDV7TwIf8M+gFgSPtDV7TwIf8M+ibEVPmbib7sIf8M+ibEVPmbib7sIf8M+gFgSPjTnFL0If8M+gFgSPjTnFL0If8M+V24IPm/Vir0Kf8M+V24IPm/Vir0Kf8M+KqnwPSsrxr0Kf8M+KqnwPSsrxr0Kf8M+R1PFPRYt+r0Kf8M+R1PFPRYt+r0Kf8M+VIWQPcVtEr4Lf8M+VIWQPcVtEr4Lf8M+po0oPVFJIr4Nf8M+po0oPVFJIr4Nf8M+XUMXPCcNLL4Nf8M+XUMXPCcNLL4Nf8M+GUvEvEJZL74Nf8M+GUvEvEJZL74Nf8M+7xtqvSUNLL4Pf8M+7xtqvSUNLL4Pf8M+Xmy2vU5JIr4Rf8M+Xmy2vU5JIr4Rf8M+5aryvcJtEr4Rf8M+5aryvcJtEr4Rf8M+a7wTvhAt+r0Tf8M+a7wTvhAt+r0Tf8M+W2cpviQrxr0Tf8M+W2cpviQrxr0Tf8M+HIE5vmfVir0Tf8M+HIE5vmfVir0Tf8M+RGtDviLnFL0Tf8M+RGtDviLnFL0Tf8M+Dm9ivuc4Dz2/M68+Dm9ivuc4Dz2/M68+pmNmvjbhb7u/M68+pmNmvjbhb7u/M68+OrhWvrOtkz2/M68+OrhWvrOtkz2/M68+YrJDvlTI2T29M68+YrJDvlTI2T29M68+rBgqvlqdCz69M68+rBgqvlqdCz69M68++OYKvifUJD67M68++OYKvifUJD67M68+QKDOvXuQNz66M68+QKDOvXuQNz66M68+mGSBvQ4aQz66M68+mGSBvQ4aQz66M68+CUvEvFn/Rj63M68+CUvEvFn/Rj63M68+pPh5PA0aQz63M68+pPh5PA0aQz63M68+dvVYPXqQNz61M68+dvVYPXqQNz61M68+ZKizPSTUJD61M68+ZKizPSTUJD61M68+zgvyPVadCz60M68+zgvyPVadCz60M68+mp8SPkvI2T2yM68+mp8SPkvI2T2yM68+cKUlPqqtkz2yM68+cKUlPqqtkz2yM68+RVwxPtI4Dz2yM68+RVwxPtI4Dz2yM68+2lA1PoDib7uyM68+2lA1PoDib7uyM68+RFwxPis1Lb2yM68+RFwxPis1Lb2yM68+b6UlPtKror2yM68+b6UlPtKror2yM68+mZ8SPnvG6L2yM68+mZ8SPnvG6L2yM68+xwvyPWkcE760M68+xwvyPWkcE760M68+XKizPTRTLL61M68+XKizPTRTLL61M68+Y/VYPYwPP761M68+Y/VYPYwPP761M68+Uvh5PBuZSr63M68+Uvh5PBuZSr63M68+M0vEvGh+Tr63M68+M0vEvGh+Tr63M68+omSBvRqZSr66M68+omSBvRqZSr66M68+S6DOvYoPP766M68+S6DOvYoPP766M68+/eYKvjFTLL67M68+/eYKvjFTLL67M68+sBgqvmYcE769M68+sBgqvmYcE769M68+ZLJDvnHG6L29M68+ZLJDvnHG6L29M68+PLhWvsmror2/M68+PLhWvsmror2/M68+D29ivhc1Lb2/M68+D29ivhc1Lb2/M68+Dm9ivuc4Dz30P6E+pmNmvjbhb7v0P6E+OrhWvrOtkz30P6E+YrJDvlTI2T3zP6E+rRgqvlqdCz7yP6E++eYKvifUJD7wP6E+RqDOvXuQNz7wP6E+m2SBvQ4aQz7wP6E+GUvEvFn/Rj7tP6E+g/h5PA0aQz7tP6E+cfVYPXqQNz7qP6E+YKizPSTUJD7qP6E+ygvyPVadCz7pP6E+mZ8SPkvI2T3nP6E+cKUlPqqtkz3nP6E+RFwxPtI4Dz3nP6E+2VA1PoDib7vnP6E+Q1wxPis1Lb3nP6E+bqUlPtKror3nP6E+mJ8SPnvG6L3nP6E+wgvyPWkcE77pP6E+WKizPTRTLL7qP6E+XPVYPYwPP77qP6E+MPh5PBuZSr7tP6E+Q0vEvGh+Tr7tP6E+pmSBvRqZSr7wP6E+T6DOvYoPP77wP6E+/uYKvjFTLL7wP6E+sRgqvmYcE77yP6E+ZbJDvnHG6L3zP6E+PLhWvsmror30P6E+D29ivhc1Lb30P6E+15p6vuIpIj28+oU+qAh/viLhb7u8+oU+/3xtvoNBpj28+oU+IjBYvrXA9D26+oU+04U7vinHHD64+oU+FJgYvrUCOT63+oU+/nzhvUD9TT61+oU+SQKLvXDoWj61+oU+NUvEvB5FXz6y+oU+v3KjPG/oWj6y+oU+y65+PT/9TT6v+oU+hgrPPbICOT6v+oU+BXMKPibHHD6u+oU+Ux0nPqzA9D2s+oU+LGo8PnhBpj2s+oU+BohJPswpIj2s+oU+1fVNPpTib7us+oU+BIhJPicmQL2s+oU+Kmo8Pqc/tb2s+oU+UB0nPm7fAb6s+oU+AHMKPjpGJL6u+oU+ewrPPcSBQL6v+oU+s65+PVF8Vb6v+oU+kXKjPHtnYr6y+oU+ZEvEvC7EZr6y+oU+VAKLvXpnYr61+oU+CX3hvU58Vb61+oU+GJgYvsGBQL63+oU+14U7vjZGJL64+oU+JzBYvmnfAb66+oU+An1tvps/tb28+oU+2Jp6vhAmQL28+oU+3QyAvnB4Jj3x/Xg+3QyAvnB4Jj3x/Xg+jVGCvhbhb7vz/Xg+jVGCvhbhb7vz/Xg+Qqpyvtt6qj3w/Xg+Qqpyvtt6qj3w/Xg+2dhcvori+j3w/Xg+2dhcvori+j3w/Xg+J3w/viuuID7u/Xg+J3w/viuuID7u/Xg+B7UbvmyZPT7r/Xg+B7UbvmyZPT7r/Xg+58blvYMWUz7p/Xg+58blvYMWUz7p/Xg+/zGNvRdSYD7n/Xg+/zGNvRdSYD7n/Xg+S0vEvO3JZD7k/Xg+S0vEvO3JZD7k/Xg+azGsPBdSYD7i/Xg+azGsPBdSYD7i/Xg+QaGDPYEWUz7e/Xg+QaGDPYEWUz7e/Xg+XkTVPWmZPT7b/Xg+XkTVPWmZPT7b/Xg+T2kOPiauID7X/Xg+T2kOPiauID7X/Xg+A8YrPoDi+j3V/Xg+A8YrPoDi+j3V/Xg+a5dBPtB6qj3U/Xg+a5dBPtB6qj3U/Xg+5gZPPll4Jj3U/Xg+5gZPPll4Jj3U/Xg+Q5BTPpLib7vS/Xg+Q5BTPpLib7vS/Xg+4wZPPqN0RL3U/Xg+4wZPPqN0RL3U/Xg+apdBPvJ4ub3U/Xg+apdBPvJ4ub3U/Xg+/8UrPlTwBL7V/Xg+/8UrPlTwBL7V/Xg+S2kOPjYtKL7X/Xg+S2kOPjYtKL7X/Xg+VUTVPXYYRb7b/Xg+VUTVPXYYRb7b/Xg+N6GDPY+VWr7e/Xg+N6GDPY+VWr7e/Xg+OzGsPCDRZ77i/Xg+OzGsPCDRZ77i/Xg+e0vEvPhIbL7k/Xg+e0vEvPhIbL7k/Xg+DDKNvR7RZ77n/Xg+DDKNvR7RZ77n/Xg+8sblvY6VWr7p/Xg+8sblvY6VWr7p/Xg+C7UbvnMYRb7r/Xg+C7UbvnMYRb7r/Xg+K3w/vjMtKL7u/Xg+K3w/vjMtKL7u/Xg+3NhcvlDwBL7w/Xg+3NhcvlDwBL7w/Xg+RapyvuZ4ub3w/Xg+RapyvuZ4ub3w/Xg+3gyAvox0RL3x/Xg+3gyAvox0RL3x/Xg+Kn6Qvok9QD31jFo+Kn6Qvok9QD31jFo+UhWTvvzgb7v1jFo+UhWTvvzgb7v1jFo+MtKIvjfBwz31jFo+MtKIvjfBwz31jFo+ybl4vgvKDz7xjFo+ybl4vgvKDz7xjFo+nTFXvgMIOD7xjFo+nTFXvgMIOD7xjFo+xVUuvqAOWT7ujFo+xVUuvqAOWT7ujFo+dHD/vfeYcT7sjFo+dHD/vfeYcT7sjFo+Ikeavc9agD7njFo+Ikeavc9agD7njFo+WUvEvPPngj7jjFo+WUvEvPPngj7jjFo+24XgPM5agD7fjFo+24XgPM5agD7fjFo+xUqdPfSYcT7cjFo+xUqdPfSYcT7cjFo+1oX6PZ0OWT7XjFo+1oX6PZ0OWT7XjFo+wx4mPv4HOD7VjFo+wx4mPv4HOD7VjFo+8aZHPgbKDz7UjFo+8aZHPgbKDz7UjFo+jJFgPivBwz3SjFo+jJFgPivBwz3SjFo+eOlvPm09QD3SjFo+eOlvPm09QD3SjFo+xhd1Pq7ib7vSjFo+xhd1Pq7ib7vSjFo+dulvPs05Xr3SjFo+dulvPs05Xr3SjFo+iZFgPla/0r3SjFo+iZFgPla/0r3SjFo+7KZHPhpJF77UjFo+7KZHPhpJF77UjFo+vx4mPhOHP77VjFo+vx4mPhOHP77VjFo+zIX6PayNYL7XjFo+zIX6PayNYL7XjFo+uUqdPQAYeb7cjFo+uUqdPQAYeb7cjFo+pYXgPFMahL7fjFo+pYXgPFMahL7fjFo+kUvEvHanhr7jjFo+kUvEvHanhr7jjFo+MEeavVIahL7njFo+MEeavVIahL7njFo+gXD/vf0Xeb7sjFo+gXD/vf0Xeb7sjFo+y1UuvqiNYL7ujFo+y1UuvqiNYL7ujFo+oDFXvg2HP77xjFo+oDFXvg2HP77xjFo+zbl4vhRJF77xjFo+zbl4vhRJF77xjFo+NNKIvkm/0r31jFo+NNKIvkm/0r31jFo+Kn6QvrI5Xr31jFo+Kn6QvrI5Xr31jFo+MX6Qvpk9QD3qJoY7MX6Qvpk9QD3qJoY7WRWTvvzgb7v1JoY7WRWTvvzgb7v1JoY7OdKIvjfBwz3JJoY7OdKIvjfBwz3JJoY717l4vgvKDz6UJoY717l4vgvKDz6UJoY7rDFXvgMIOD5LJoY7rDFXvgMIOD5LJoY71FUuvqAOWT7zJYY71FUuvqAOWT7zJYY7kXD/vfeYcT6NJYY7kXD/vfeYcT6NJYY7QUeavc9agD4iJYY7QUeavc9agD4iJYY70kvEvPPngj6wJIY70kvEvPPngj6wJIY7Y4XgPM5agD4+JIY7Y4XgPM5agD4+JIY7qEqdPfSYcT7PI4Y7qEqdPfSYcT7PI4Y7uoX6PZ0OWT5rI4Y7uoX6PZ0OWT5rI4Y7tB4mPv4HOD4SI4Y7tB4mPv4HOD4SI4Y74aZHPgbKDz7LIoY74aZHPgbKDz7LIoY7fJFgPivBwz2WIoY7fJFgPivBwz2WIoY7aOlvPn49QD10IoY7aOlvPn49QD10IoY7thd1Pq7ib7tpIoY7thd1Pq7ib7tpIoY7ZulvPs05Xr10IoY7ZulvPs05Xr10IoY7epFgPla/0r2WIoY7epFgPla/0r2WIoY73aZHPhpJF77LIoY7rx4mPhOHP74SI4Y7rx4mPhOHP74SI4Y7rYX6PayNYL5rI4Y7rYX6PayNYL5rI4Y7mkqdPQAYeb7PI4Y7mkqdPQAYeb7PI4Y7LYXgPFMahL4+JIY7LYXgPFMahL4+JIY7CUzEvHanhr6wJIY7CUzEvHanhr6wJIY7TkeavVIahL4iJYY7TkeavVIahL4iJYY7nnD/vf0Xeb6NJYY7nnD/vf0Xeb6NJYY721UuvqiNYL7zJYY721UuvqiNYL7zJYY7sTFXvg2HP75LJoY7sTFXvg2HP75LJoY73Ll4vhRJF76UJoY73Ll4vhRJF76UJoY7PNKIvkm/0r3JJoY7PNKIvkm/0r3JJoY7MX6QvrI5Xr3qJoY7MX6QvrI5Xr3qJoY7enD/vfeYcT7Tuzg+enD/vfeYcT7Tuzg+jHD/vfeYcT4BChg9jHD/vfeYcT4BChg90lUuvqAOWT4sChg90lUuvqAOWT4sChg9yFUuvqAOWT7euzg+yFUuvqAOWT7euzg+vB4mPhOHP761uzg+vB4mPhOHP761uzg+sh4mPhOHP76TCRg9sh4mPhOHP76TCRg94aZHPhpJF76oCRg94aZHPhpJF76oCRg96qZHPhpJF769uzg+6qZHPhpJF769uzg+J0eavc9agD7Puzg+J0eavc9agD7Puzg+O0eavc9agD7zCRg9O0eavc9agD7zCRg9yIX6PayNYL64uzg+yIX6PayNYL64uzg+s4X6PayNYL6cCRg9s4X6PayNYL6cCRg9b0vEvPPngj7Muzg+b0vEvPPngj7Muzg+vUvEvPPngj7kCRg9vUvEvPPngj7kCRg9s0qdPQAYeb68uzg+s0qdPQAYeb68uzg+oEqdPQAYeb6pCRg9oEqdPQAYeb6pCRg9xoXgPM5agD7Guzg+xoXgPM5agD7Guzg+dYXgPM5agD7HCRg9dYXgPM5agD7HCRg9kIXgPFMahL6/uzg+kIXgPFMahL6/uzg+QIXgPFMahL63CRg9QIXgPFMahL63CRg9wEqdPfSYcT7Euzg+wEqdPfSYcT7Euzg+rUqdPfSYcT65CRg9rUqdPfSYcT65CRg9p0vEvHanhr7Euzg+p0vEvHanhr7Euzg+9EvEvHanhr7FCRg99EvEvHanhr7FCRg904X6PZ0OWT68uzg+04X6PZ0OWT68uzg+v4X6PZ0OWT6sCRg9v4X6PZ0OWT6sCRg9NUeavVIahL7Huzg+NUeavVIahL7Huzg+SEeavVIahL7TCRg9SEeavVIahL7TCRg9wB4mPv4HOD65uzg+wB4mPv4HOD65uzg+th4mPv4HOD6iCRg9th4mPv4HOD6iCRg9hnD/vf0Xeb7Luzg+hnD/vf0Xeb7Luzg+mHD/vf0Xeb7hCRg9mHD/vf0Xeb7hCRg976ZHPgbKDz65uzg+76ZHPgbKDz65uzg+5KZHPgbKDz6YCRg95KZHPgbKDz6YCRg9zlUuvqiNYL7Ouzg+zlUuvqiNYL7Ouzg+2FUuvqiNYL7tCRg92FUuvqiNYL7tCRg9ipFgPivBwz22uzg+ipFgPivBwz22uzg+f5FgPivBwz2SCRg9f5FgPivBwz2SCRg9K36Qvpk9QD3cuzg+K36Qvpk9QD3cuzg+MX6Qvok9QD0dChg9MX6Qvok9QD0dChg9WRWTvvzgb7s9Chg9WRWTvvzgb7s9Chg9UxWTvvzgb7vkuzg+UxWTvvzgb7vkuzg+ojFXvg2HP77Vuzg+ojFXvg2HP77Vuzg+rTFXvg2HP74IChg9rTFXvg2HP74IChg9dulvPn49QD2xuzg+dulvPn49QD2xuzg+a+lvPm09QD1+CRg9a+lvPm09QD1+CRg9M9KIvjfBwz3cuzg+M9KIvjfBwz3cuzg+ONKIvjfBwz0nChg9ONKIvjfBwz0nChg9z7l4vhRJF77Vuzg+z7l4vhRJF77Vuzg+2bl4vhRJF74RChg92bl4vhRJF74RChg9xBd1Pq7ib7uxuzg+xBd1Pq7ib7uxuzg+uRd1Pq7ib7t8CRg9uRd1Pq7ib7t8CRg9y7l4vgvKDz7auzg+y7l4vgvKDz7auzg+1Ll4vgvKDz4hChg91Ll4vgvKDz4hChg9NdKIvkm/0r3Yuzg+NdKIvkm/0r3Yuzg+O9KIvkm/0r0XChg9O9KIvkm/0r0XChg9dOlvPsQ5Xr2xuzg+dOlvPsQ5Xr2xuzg+aulvPs05Xr1+CRg9aulvPs05Xr1+CRg9nzFXvgMIOD7Zuzg+nzFXvgMIOD7Zuzg+qDFXvgMIOD4YChg9qDFXvgMIOD4YChg9K36Qvqo5Xr3Yuzg+K36Qvqo5Xr3Yuzg+MX6QvrI5Xr0dChg9MX6QvrI5Xr0dChg9h5FgPla/0r2yuzg+h5FgPla/0r2yuzg+fpFgPla/0r2CCRg9fpFgPla/0r2CCRg9enD/vfeYcT63aCA+enD/vfeYcT63aCA+h3D/vfeYcT7DVnk9h3D/vfeYcT7DVnk90VUuvqAOWT7vVnk90VUuvqAOWT7vVnk9ylUuvqAOWT7JaCA+ylUuvqAOWT7JaCA+uh4mPhOHP76IaCA+uh4mPhOHP76IaCA+sh4mPhOHP74UVnk9sh4mPhOHP74UVnk94aZHPhpJF74qVnk94aZHPhpJF74qVnk956ZHPhpJF76YaCA+56ZHPhpJF76YaCA+Kkeavc9agD6yaCA+Kkeavc9agD6yaCA+Nkeavc9agD61Vnk9Nkeavc9agD61Vnk9xoX6PayNYL6MaCA+xoX6PayNYL6MaCA+uIX6PayNYL4fVnk9uIX6PayNYL4fVnk9fkvEvPPngj6waCA+fkvEvPPngj6waCA+rkvEvPPngj6WVnk9rkvEvPPngj6WVnk9skqdPQAYeb6PaCA+skqdPQAYeb6PaCA+pUqdPQAYeb4sVnk9pUqdPQAYeb4sVnk9toXgPM5agD6iaCA+toXgPM5agD6iaCA+g4XgPM5agD5JVnk9g4XgPM5agD5JVnk9gYXgPFMahL6SaCA+gYXgPFMahL6SaCA+ToXgPFMahL45Vnk9ToXgPFMahL45Vnk9vkqdPfSYcT6faCA+vkqdPfSYcT6faCA+sUqdPfSYcT49Vnk9sUqdPfSYcT49Vnk9tkvEvHanhr6caCA+tkvEvHanhr6caCA+5UvEvHanhr5GVnk95UvEvHanhr5GVnk90YX6PZ0OWT6caCA+0YX6PZ0OWT6caCA+w4X6PZ0OWT4vVnk9w4X6PZ0OWT4vVnk9OEeavVIahL6faCA+OEeavVIahL6faCA+REeavVIahL5WVnk9REeavVIahL5WVnk9vh4mPv4HOD6YaCA+vh4mPv4HOD6YaCA+tx4mPv4HOD4kVnk9tx4mPv4HOD4kVnk9hnD/vf0Xeb6jaCA+hnD/vf0Xeb6jaCA+lXD/vf0Xeb5jVnk9lXD/vf0Xeb5jVnk966ZHPgbKDz6UaCA+66ZHPgbKDz6UaCA+5KZHPgbKDz4bVnk95KZHPgbKDz4bVnk90FUuvqiNYL6laCA+0FUuvqiNYL6laCA+11UuvqiNYL5wVnk911UuvqiNYL5wVnk9hpFgPivBwz2RaCA+hpFgPivBwz2RaCA+f5FgPivBwz0GVnk9f5FgPivBwz0GVnk9LH6Qvpk9QD23aCA+LH6Qvpk9QD23aCA+L36Qvok9QD2gVnk9L36Qvok9QD2gVnk9VxWTvvzgb7v/Vnk9VxWTvvzgb7v/Vnk9VBWTvvzgb7vQaCA+VBWTvvzgb7vQaCA+pjFXvg2HP76waCA+pjFXvg2HP76waCA+rTFXvg2HP756Vnk9rTFXvg2HP756Vnk9culvPn49QD2JaCA+culvPn49QD2JaCA+a+lvPm09QD0BVnk9a+lvPm09QD0BVnk9NNKIvjfBwz2/aCA+NNKIvjfBwz2/aCA+NtKIvjfBwz3ZVnk9NtKIvjfBwz3ZVnk907l4vhRJF76xaCA+07l4vhRJF76xaCA+2bl4vhRJF76VVnk92bl4vhRJF76VVnk9wBd1Pq7ib7uJaCA+wBd1Pq7ib7uJaCA+uRd1Pq7ib7v/VXk9uRd1Pq7ib7v/VXk9zrl4vgvKDz69aCA+zrl4vgvKDz69aCA+1Ll4vgvKDz7kVnk91Ll4vgvKDz7kVnk9NtKIvkm/0r23aCA+NtKIvkm/0r23aCA+OdKIvkm/0r2aVnk9OdKIvkm/0r2aVnk9celvPsQ5Xr2JaCA+celvPsQ5Xr2JaCA+aulvPs05Xr0BVnk9aulvPs05Xr0BVnk9ozFXvgMIOD68aCA+ozFXvgMIOD68aCA+qDFXvgMIOD7ZVnk9qDFXvgMIOD7ZVnk9LH6Qvqo5Xr23aCA+LH6Qvqo5Xr23aCA+L36QvrI5Xr2gVnk9L36QvrI5Xr2gVnk9g5FgPla/0r2JaCA+g5FgPla/0r2JaCA+fpFgPla/0r0GVnk9fpFgPla/0r0GVnk9zVH2vTvBZj7DVnk9zVH2vTvBZj7DVnk9z1H2vTvBZj4BChg9z1H2vTvBZj4BChg9CbcnvodMTz7JaCA+CbcnvodMTz7JaCA+B7cnvodMTz7euzg+B7cnvodMTz7euzg+sbEdPp06N74WVnk9sbEdPp06N74WVnk9sLEdPp06N76VCRg9sLEdPp06N76VCRg9hr49Pu7DEL6YaCA+hr49Pu7DEL6YaCA+iL49Pu7DEL69uzg+iL49Pu7DEL69uzg++qCVvekydT6zVnk9+qCVvekydT6zVnk9/6CVvekydT7xCRg9/6CVvekydT7xCRg9OUjtPZLLVr4hVnk9OUjtPZLLVr4hVnk9NEjtPZLLVr6fCRg9NEjtPZLLVr6fCRg9sEvEvHYTej6WVnk9sEvEvHYTej6WVnk9vUvEvHYTej7kCRg9vUvEvHYTej7kCRg96CuUPUVAbr4uVnk96CuUPUVAbr4uVnk95iuUPUVAbr6rCRg95iuUPUVAbr6rCRg9juzNPOcydT5LVnk9juzNPOcydT5LVnk9f+zNPOcydT7ICRg9f+zNPOcydT7ICRg9W+zNPPKxfL47Vnk9W+zNPPKxfL47Vnk9TOzNPPKxfL64CRg9TOzNPPKxfL64CRg99SuUPTnBZj4/Vnk99SuUPTnBZj4/Vnk98iuUPTnBZj67CRg98iuUPTnBZj67CRg95EvEvD/JgL5GVnk95EvEvD/JgL5GVnk98kvEvD/JgL7FCRg98kvEvD/JgL7FCRg9QkjtPYRMTz4xVnk9QkjtPYRMTz4xVnk9P0jtPYRMTz6vCRg9P0jtPYRMTz6vCRg9B6GVvfCxfL5UVnk9B6GVvfCxfL5UVnk9DKGVvfCxfL7RCRg9DKGVvfCxfL7RCRg9tLEdPoq7Lz4mVnk9tLEdPoq7Lz4mVnk9tLEdPoq7Lz6lCRg9tLEdPoq7Lz6lCRg92lH2vUJAbr5jVnk92lH2vUJAbr5jVnk93FH2vUJAbr7hCRg93FH2vUJAbr7hCRg9hL49PtpECT4fVnk9hL49PtpECT4fVnk9g749PtpECT6bCRg9g749PtpECT6bCRg9F7cnvo/LVr5sVnk9F7cnvo/LVr5sVnk9GLcnvo/LVr7rCRg9GLcnvo/LVr7rCRg9Oo9VPqvFuj0IVnk9Oo9VPqvFuj0IVnk9Oo9VPqvFuj2VCRg9Oo9VPqvFuj2VCRg9QKaKvv8UNz2cVnk9QKaKvv8UNz2cVnk9QqaKvv8UNz0aChg9QqaKvv8UNz0aChg9FyCNvgXhb7vQaCA+FyCNvgXhb7vQaCA+FiCNvgXhb7vkuzg+FiCNvgXhb7vkuzg+qsROvpc6N755Vnk9qsROvpc6N755Vnk9qsROvpc6N74HChg9qsROvpc6N74HChg9kDlkPuYUNz0EVnk9kDlkPuYUNz0EVnk9kDlkPuYUNz2CCRg9kDlkPuYUNz2CCRg9FlGDvrbFuj3WVnk9FlGDvrbFuj3WVnk9GFGDvrbFuj0kChg9GFGDvrbFuj0kChg9eNFuvujDEL6RVnk9eNFuvujDEL6RVnk9eNFuvujDEL4OChg9eNFuvujDEL4OChg9QC1pPqPib7sCVnk9QC1pPqPib7sCVnk9QC1pPqPib7t/CRg9QC1pPqPib7t/CRg9dNFuvt9ECT7gVnk9dNFuvt9ECT7gVnk9dNFuvt9ECT4eChg9dNFuvt9ECT4eChg9F1GDvs7Dyb2XVnk9F1GDvs7Dyb2XVnk9GVGDvs7Dyb0UChg9GVGDvs7Dyb0UChg9jjlkPkQRVb0EVnk9jjlkPkQRVb0EVnk9jjlkPkQRVb2CCRg9jjlkPkQRVb2CCRg9pcROvpC7Lz7YVnk9pcROvpC7Lz7YVnk9pcROvpC7Lz4XChg9pcROvpC7Lz4XChg9QKaKvioRVb2cVnk9QKaKvioRVb2cVnk9QqaKvioRVb0aChg9QqaKvioRVb0aChg9No9VPtnDyb0IVnk9No9VPtnDyb0IVnk9No9VPtnDyb2FCRg9No9VPtnDyb2FCRg9QY9VPtbDyb2yuzg+QY9VPtbDyb2yuzg+f749Pu7DEL6rCRg9f749Pu7DEL6rCRg9PaaKviIRVb3Yuzg+PaaKviIRVb3Yuzg+HCCNvgXhb7s6Chg9HCCNvgXhb7s6Chg9msROvpC7Lz7Xuzg+msROvpC7Lz7Xuzg+EbcnvodMTz4qChg9EbcnvodMTz4qChg9mTlkPjsRVb2yuzg+mTlkPjsRVb2yuzg+ElGDvsrDyb3Xuzg+ElGDvsrDyb3Xuzg+atFuvt9ECT7auzg+atFuvt9ECT7auzg+Si1pPqPib7uyuzg+Si1pPqPib7uyuzg+btFuvujDEL7Vuzg+btFuvujDEL7Vuzg+ElGDvr/Fuj3cuzg+ElGDvr/Fuj3cuzg+mzlkPuYUNz2yuzg+mzlkPuYUNz2yuzg+n8ROvpc6N77Tuzg+n8ROvpc6N77Tuzg+PaaKvv8UNz3cuzg+PaaKvv8UNz3cuzg+RI9VPrPFuj22uzg+RI9VPrPFuj22uzg+Drcnvo/LVr7Ouzg+Drcnvo/LVr7Ouzg+jb49PtpECT65uzg+jb49PtpECT65uzg+yVH2vUJAbr7Luzg+yVH2vUJAbr7Luzg+vrEdPoq7Lz68uzg+vrEdPoq7Lz68uzg++KCVvfCxfL7Huzg++KCVvfCxfL7Huzg+UkjtPYRMTz68uzg+UkjtPYRMTz68uzg+pUvEvD/JgL7Euzg+pUvEvD/JgL7Euzg+BSyUPTnBZj7Euzg+BSyUPTnBZj7Euzg+oezNPPKxfL6/uzg+oezNPPKxfL6/uzg+1OzNPOcydT7Guzg+1OzNPOcydT7Guzg++SuUPUVAbr68uzg++SuUPUVAbr68uzg+cEvEvHYTej7Muzg+cEvEvHYTej7Muzg+SEjtPZLLVr64uzg+SEjtPZLLVr64uzg+66CVvekydT7Puzg+66CVvekydT7Puzg+urEdPp06N763uzg+urEdPp06N763uzg+vVH2vTvBZj7Tuzg+vVH2vTvBZj7Tuzg+v1H2vTvBZj62aCA+v1H2vTvBZj62aCA+EbcnvodMTz7sVnk9EbcnvodMTz7sVnk9uLEdPp06N76LaCA+uLEdPp06N76LaCA+f749Pu7DEL4tVnk9f749Pu7DEL4tVnk97qCVvekydT6yaCA+7qCVvekydT6yaCA+RkjtPZLLVr6MaCA+RkjtPZLLVr6MaCA+gEvEvHYTej6waCA+gEvEvHYTej6waCA+9SuUPUVAbr6PaCA+9SuUPUVAbr6PaCA+xOzNPOcydT6iaCA+xOzNPOcydT6iaCA+kezNPPKxfL6SaCA+kezNPPKxfL6SaCA+ASyUPTnBZj6faCA+ASyUPTnBZj6faCA+tEvEvD/JgL6caCA+tEvEvD/JgL6caCA+UEjtPYRMTz6caCA+UEjtPYRMTz6caCA++6CVvfCxfL6faCA++6CVvfCxfL6faCA+vLEdPoq7Lz6baCA+vLEdPoq7Lz6baCA+y1H2vUJAbr6iaCA+y1H2vUJAbr6iaCA+i749PtpECT6UaCA+i749PtpECT6UaCA+ELcnvo/LVr6laCA+ELcnvo/LVr6laCA+QY9VPrPFuj2RaCA+QY9VPrPFuj2RaCA+PqaKvv8UNz23aCA+PqaKvv8UNz23aCA+GiCNvgXhb7v9Vnk9GiCNvgXhb7v9Vnk9osROvpc6N76uaCA+osROvpc6N76uaCA+lzlkPuYUNz2JaCA+lzlkPuYUNz2JaCA+ElGDvr/Fuj2/aCA+ElGDvr/Fuj2/aCA+ctFuvujDEL6xaCA+ctFuvujDEL6xaCA+Ry1pPqPib7uJaCA+Ry1pPqPib7uJaCA+bdFuvt9ECT69aCA+bdFuvt9ECT69aCA+E1GDvsrDyb23aCA+E1GDvsrDyb23aCA+ljlkPjsRVb2JaCA+ljlkPjsRVb2JaCA+nsROvpC7Lz66aCA+nsROvpC7Lz66aCA+PqaKviIRVb23aCA+PqaKviIRVb23aCA+Po9VPtbDyb2JaCA+Po9VPtbDyb2JaCA+OL9rPsQOQD4NGDO+OL9rPsQOQD4NGDO+K0l1PtzeMz4V8y2+K0l1PtzeMz4V8y2+AjV+Pm94Jj7AuSu+AjV+Pm94Jj7AuSu+qQ6GPsL+DD5ruyy+qQ6GPsL+DD5ruyy+jTONPl3A5j0lPDO+jTONPl3A5j0lPDO+6fmSPgB5rj2oUz2+6fmSPgB5rj2oUz2+wH6WPv30aT24qUW+wH6WPv30aT24qUW+0YCYPkwF8Twaz0q+0YCYPkwF8Twaz0q+lJmZPtwAHLkGfky+lJmZPtwAHLkGfky+0YCYPpl187waz0q+0YCYPpl187waz0q+wH6WPgsta720qUW+wH6WPgsta720qUW+6fmSPgEVr72gUz2+6fmSPgEVr72gUz2+ijONPmFc570oPDO+ijONPmFc570oPDO+qQ6GPsJMDb5nuyy+qQ6GPsJMDb5nuyy++TR+PmvGJr67uSu++TR+PmvGJr67uSu+Kkl1PtUsNL4V8y2+Kkl1PtUsNL4V8y2+M79rPsRcQL4JGDO+M79rPsRcQL4JGDO+yuphPvbiSr7QlTu+yuphPvbiSr7QlTu+qFBYPjGDU75iZka+qFBYPjGDU75iZka+tlFEPucdY74YE2G+tlFEPucdY74YE2G+FaMvPk0tc741dX2+FaMvPk0tc741dX2+xTcVPoC/g77FQpG+xTcVPoC/g77FQpG+nh/xPUKwjr4bdai+nh/xPUKwjr4bdai+nh/xPUKwjr4bdai+qM65PWbTk74Odai+qM65PWbTk74Odai+Wg08PUEMmL6Mdqi+Wg08PUEMmL6Mdqi+kqC/tISJmb7tdai+kqC/tISJmb7tdai+Fg48vUMMmL6Hdqi+Fg48vUMMmL6Hdqi+Ac+5vWbTk74Mdai+Ac+5vWbTk74Mdai++B/xvT+wjr4Udai++B/xvT+wjr4Udai++B/xvT+wjr4Udai+7jcVvny/g768QpG+7jcVvny/g768QpG+PaMvvkotc74pdX2+PaMvvkotc74pdX2+3FFEvuodY74CE2G+3FFEvuodY74CE2G+zFBYvjCDU75IZka+zFBYvjCDU75IZka+8+phvvDiSr60lTu+8+phvvDiSr60lTu+Ub9rvsZcQL76FzO+Ub9rvsZcQL76FzO+RUl1vtIsNL728i2+RUl1vtIsNL728i2+HzV+vmjGJr6fuSu+HzV+vmjGJr6fuSu+vw6GvsFMDb5Guyy+vw6GvsFMDb5Guyy+nTONvk9c570HPDO+nTONvk9c570HPDO++PmSvu0Ur71+Uz2++PmSvu0Ur71+Uz2+0H6Wvuwsa72TqUW+0H6Wvuwsa72TqUW+4YCYvkF187zzzkq+4YCYvkF187zzzkq+oZmZvvnhG7nkfUy+oZmZvvnhG7nkfUy+4oCYvooF8Tzzzkq+4oCYvooF8Tzzzkq+zX6Wvhv1aT2WqUW+zX6Wvhv1aT2WqUW+9vmSvgh5rj2DUz2+9vmSvgh5rj2DUz2+mTONvmDA5j0HPDO+mTONvmDA5j0HPDO+ug6Gvsj+DD5Kuyy+ug6Gvsj+DD5Kuyy+IDV+vnV4Jj6juSu+IDV+vnV4Jj6juSu+Rkl1vtzeMz758i2+Rkl1vtzeMz758i2+WL9rvs0OQD7yFzO+WL9rvs0OQD7yFzO+6ephvviUSj6tlTu+6ephvviUSj6tlTu+xlBYvjg1Uz5LZka+xlBYvjg1Uz5LZka+2FFEvvHPYj4CE2G+2FFEvvHPYj4CE2G+O6MvvlPfcj4gdX2+O6MvvlPfcj4gdX2+6zcVvoWYgz66QpG+6zcVvoWYgz66QpG+7h/xvUmJjj4Sdai+7h/xvUmJjj4Sdai+7h/xvUmJjj4Sdai+/865vXKskz4Kdai+/865vXKskz4Kdai++g08vUrllz5/dqi++g08vUrllz5/dqi+h72QtLKpmT7rdai+h72QtLKpmT7rdai+WQ08PUrllz6Idqi+WQ08PUrllz6Idqi+qs65PW+skz4Sdai+qs65PW+skz4Sdai+px/xPUeJjj4Zdai+px/xPUeJjj4Zdai+px/xPUeJjj4Zdai+zDcVPoSYgz7DQpG+zDcVPoSYgz7DQpG+HKMvPlDfcj41dX2+HKMvPlDfcj41dX2+uVFEPuzPYj4YE2G+uVFEPuzPYj4YE2G+q1BYPjI1Uz5iZka+q1BYPjI1Uz5iZka+0OphPu+USj7UlTu+0OphPu+USj7UlTu+P5thPkDNNz6LXha9NtZqPqY2LD6NXha9Rc1zPlypHz6SXha95CCBPtvQBz6UXha9sTSHPs/23D2YXha9mCWMPpdgpj2bXha9xpiPPotBXz2dXha99qCRPpsz5jydXha9alqSPhSJDrmeXha9FJqRPmFl6LydXha9pouPPt5KYL2VXha9hxKMPpvYpr2TXha9LhyHPoVe3b2QXha99QOBPhj7B76EXha9Yo1zPpLHH76CXha99pNqPtdNLL5+Xha9V1dhPq7dN757Xha9AjtYPo4uQr55Xha9bqlPPtELS754Xha9Va89PvFvW75yXha9kJwpPnDUar5rXha9NocOPlete75lXha9A8/gPYMHhb5eXha9fAOtPX6kib5WXha98SwwPbhwjr5MXha968iqs9wUkL4/Xha9FS0wvbdwjr4yXha9jQOtvX6kib43Xha9Fc/gvYMHhb4wXha9RIcOvk+te74oXha9nZwpvmnUar4iXha9Xq89vu5vW74cXha9e6lPvssLS74WXha9EztYvoMuQr4WXha9YVdhvq7dN74TXha9/pNqvtRNLL4QXha9a41zvovHH74MXha9+gOBvg/7B74JXha9MhyHvm5e3b0OXha9jBKMvoPYpr0LXha9p4uPvrpKYL0IXha9FZqRvgpl6LwQXha9a1qSvqdrDrkQXha9+KCRvs8z5jwQXha9x5iPvqNBXz0QXha9mSWMvp5gpj0TXha9sTSHvs723D0WXha95SCBvt3QBz4ZXha9Ts1zvl+pHz4cXha9PtZqvqQ2LD4fXha9RpthvkPNNz4iXha99H9YvmwkQj4lXha93e5PvkYHSz4mXha9VPQ9vm52Wz4zXha9ld4pvojmaj4wXha9BcIOvmTNez44Xha9tC7hveYdhT5AXha9m0+tveK+iT5HXha9qn0wvWWPjj5SXha9wG8KMA01kD5fXha9nX0wPWWPjj5rXha9kE+tPeK+iT52Xha9ti7hPeUdhT59Xha9AsIOPmLNez6FXha9kN4pPormaj6OXha9TvQ9Pm52Wz6KXha92+5PPkMHSz6HXha98H9YPmckQj6IXha9QJthPkDNNz43efm8QJthPkDNNz43efm8N9ZqPqY2LD46efm8N9ZqPqY2LD46efm8R81zPlypHz5Aefm8R81zPlypHz5Aefm85SCBPtvQBz5Hefm85SCBPtvQBz5Hefm8sjSHPs/23D1Oefm8sjSHPs/23D1Oefm8mSWMPpdgpj1Uefm8mSWMPpdgpj1Uefm8x5iPPotBXz1Yefm8x5iPPotBXz1Yefm896CRPp0z5jxKefm896CRPp0z5jxKefm8alqSPrKIDrlKefm8alqSPrKIDrlKefm8FZqRPmBl6LxKefm8FZqRPmBl6LxKefm8pouPPt5KYL04efm8pouPPt5KYL04efm8iBKMPpvYpr00efm8iBKMPpvYpr00efm8LxyHPoVe3b0tefm8LxyHPoVe3b0tefm89gOBPhj7B74mefm89gOBPhj7B74mefm8ZI1zPpLHH74hefm8ZI1zPpLHH74hefm895NqPtdNLL4befm895NqPtdNLL4befm8WVdhPq7dN74Vefm8WVdhPq7dN74Vefm8BDtYPo4uQr4Refm8BDtYPo4uQr4Refm8b6lPPtELS74Mefm8b6lPPtELS74Mefm8Va89PvFvW74Befm8Va89PvFvW74Befm8kJwpPnDUar74ePm8kJwpPnDUar74ePm8NocOPlete77oePm8NocOPlete77oePm8Bc/gPYMHhb7XePm8Bc/gPYMHhb7XePm8fgOtPX6kib7MePm8fgOtPX6kib7MePm88SwwPbhwjr61ePm88SwwPbhwjr61ePm8y0+cs9wUkL6bePm8y0+cs9wUkL6bePm8FS0wvbdwjr6CePm8FS0wvbdwjr6CePm8iwOtvX6kib58ePm8iwOtvX6kib58ePm8E8/gvYMHhb5xePm8E8/gvYMHhb5xePm8RIcOvk+te75fePm8RIcOvk+te75fePm8nZwpvmnUar5QePm8nZwpvmnUar5QePm8Xq89vu5vW75VePm8Xq89vu5vW75VePm8ealPvssLS75MePm8ealPvssLS75MePm8ETtYvoMuQr5HePm8ETtYvoMuQr5HePm8YFdhvq7dN75DePm8YFdhvq7dN75DePm8/ZNqvtRNLL48ePm8/ZNqvtRNLL48ePm8aY1zvovHH743ePm8aY1zvovHH743ePm8+QOBvg/7B74wePm8+QOBvg/7B74wePm8MhyHvm5e3b0pePm8MhyHvm5e3b0pePm8ixKMvoPYpr0kePm8ixKMvoPYpr0kePm8pouPvrpKYL0gePm8pouPvrpKYL0gePm8FZqRvgll6LwuePm8FZqRvgll6LwuePm8alqSvkNrDrkuePm8alqSvkNrDrkuePm896CRvtEz5jwuePm896CRvtEz5jwuePm8x5iPvqNBXz0/ePm8x5iPvqNBXz0/ePm8mCWMvp5gpj1CePm8mCWMvp5gpj1CePm8sDSHvs723D1JePm8sDSHvs723D1JePm85CCBvt3QBz5QePm85CCBvt3QBz5QePm8TM1zvl+pHz5XePm8TM1zvl+pHz5XePm8PdZqvqQ2LD5dePm8PdZqvqQ2LD5dePm8RJthvkPNNz5gePm8RJthvkPNNz5gePm8839YvmwkQj5mePm8839YvmwkQj5mePm83O5PvkYHSz5pePm83O5PvkYHSz5pePm8VPQ9vm52Wz51ePm8VPQ9vm52Wz51ePm8ld4pvojmaj6AePm8ld4pvojmaj6AePm8BcIOvmTNez6OePm8BcIOvmTNez6OePm8si7hveYdhT6gePm8si7hveYdhT6gePm8mU+tveK+iT6sePm8mU+tveK+iT6sePm8qn0wvWWPjj7BePm8qn0wvWWPjj7BePm8+t/4MQ01kD7cePm8+t/4MQ01kD7cePm8nX0wPWWPjj70ePm8nX0wPWWPjj70ePm8kk+tPeK+iT77ePm8kk+tPeK+iT77ePm8uC7hPeUdhT4Hefm8uC7hPeUdhT4Hefm8AsIOPmLNez4Xefm8AsIOPmLNez4Xefm8kN4pPormaj4nefm8kN4pPormaj4nefm8TvQ9Pm52Wz4hefm8TvQ9Pm52Wz4hefm83O5PPkMHSz4uefm83O5PPkMHSz4uefm88n9YPmckQj4xefm88n9YPmckQj4xefm8DmNEPksDID50Tki0DmNEPksDID50Tki0DmNEPksDID50Tki0DmNEPksDID50Tki0+mtMPursFT7s/FC0+mtMPursFT7s/FC0+mtMPursFT7s/FC0+mtMPursFT7s/FC0zDlUPsz/Cj6Ja1m0zDlUPsz/Cj6Ja1m0zDlUPsz/Cj6Ja1m0zDlUPsz/Cj6Ja1m0Bs9gPtV77D0EBGe0Bs9gPtV77D0EBGe0Bs9gPtV77D0EBGe0Bs9gPtV77D0EBGe0m2NrPt1gwD2YcnK0m2NrPt1gwD2YcnK0m2NrPt1gwD2YcnK0m2NrPt1gwD2YcnK0xv1zPojckD0Avnu0xv1zPojckD0Avnu0xv1zPojckD0Avnu0xv1zPojckD0Avnu0XP95PvJnQj2rHYG0XP95PvJnQj2rHYG0XP95PvJnQj2rHYG0XP95PvJnQj2rHYG0/Yh9PmiEyDzuBoO0/Yh9PmiEyDzuBoO0/Yh9PmiEyDzuBoO0/Yh9PmiEyDzuBoO02st+PhzI1rhatYO02st+PhzI1rhatYO02st+PhzI1rhatYO02st+PhzI1rhatYO0AH19Pq8qyrxzAIO0AH19Pq8qyrxzAIO0AH19Pq8qyrxzAIO0AH19Pq8qyrxzAIO0gOh5PootQ706cGK0gOh5PootQ706cGK0gOh5PootQ706cGK0gOh5PootQ706cGK0l9xzPlE0kb2951u0l9xzPlE0kb2951u0l9xzPlE0kb2951u0l9xzPlE0kb2951u08jhrPnSqwL0XklK08jhrPnSqwL0XklK08jhrPnSqwL0XklK08jhrPnSqwL0XklK0ppxgPrC07L1knEa0ppxgPrC07L1knEa0ppxgPrC07L1knEa0ppxgPrC07L1knEa0LAJUPr4RC77USxm0LAJUPr4RC77USxm0LAJUPr4RC77USxm0LAJUPr4RC77USxm0TDJMPsP4Fb7IWRG0TDJMPsP4Fb7IWRG0TDJMPsP4Fb7IWRG0TDJMPsP4Fb7IWRG08CdEPkAJIL7DqQi08CdEPkAJIL7DqQi08CdEPkAJIL7DqQi08CdEPkAJIL7DqQi0rTk8PhgEKb6eMv+zrTk8PhgEKb6eMv+zrTk8PhgEKb6eMv+zrTk8PhgEKb6eMv+zM8Q0PnG7ML5OFO+zM8Q0PnG7ML5OFO+zM8Q0PnG7ML5OFO+zM8Q0PnG7ML5OFO+zM8Q0PnG7ML5OFO+zIx4lPhoAP74UVAa0Ix4lPhoAP74UVAa0Ix4lPhoAP74UVAa0Ix4lPhoAP74UVAa07KQTPj1mTL6v5eaz7KQTPj1mTL6v5eaz7KQTPj1mTL6v5eaz7KQTPj1mTL6v5eazHCP4PY4QW75uGGuzHCP4PY4QW75uGGuzHCP4PY4QW75uGGuzHCP4PY4QW75uGGuzRrHDPWeVZ742av+yRrHDPWeVZ742av+yRrHDPWeVZ742av+yRrHDPWeVZ742av+yDZuWPXWdb76YBwGyDZuWPXWdb76YBwGyDZuWPXWdb76YBwGyDZuWPXWdb76YBwGyslsZPcH3d74AcJUwslsZPcH3d74AcJUwslsZPcH3d74AcJUwslsZPcH3d74AcJUwqZgdszXTer4jWiwzqZgdszXTer4jWiwzqZgdszXTer4jWiwzqZgdszXTer4jWiwzwFsZvcP3d746CagzwFsZvcP3d746CagzwFsZvcP3d746CagzwFsZvcP3d746CagzEpuWvXWdb75XgrkzEpuWvXWdb75XgrkzEpuWvXWdb75XgrkzEpuWvXWdb75XgrkzSrHDvWeVZ76EOeozSrHDvWeVZ76EOeozSrHDvWeVZ76EOeozSrHDvWeVZ76EOeozKyP4vYgQW77E8BE0KyP4vYgQW77E8BE0KyP4vYgQW77E8BE0KyP4vYgQW77E8BE09KQTvjlmTL7haSs09KQTvjlmTL7haSs09KQTvjlmTL7haSs09KQTvjlmTL7haSs0Jh4lvhgAP74YSz40Jh4lvhgAP74YSz40Jh4lvhgAP74YSz40Jh4lvhgAP74YSz40NsQ0vm27ML6UM080NsQ0vm27ML6UM080NsQ0vm27ML6UM080NsQ0vm27ML6UM080tTk8vgwEKb7CQlc0tTk8vgwEKb7CQlc0tTk8vgwEKb7CQlc0tTk8vgwEKb7CQlc08CdEvj0JIL5i1F808CdEvj0JIL5i1F808CdEvj0JIL5i1F808CdEvj0JIL5i1F80TjJMvr74Fb5qhGg0TjJMvr74Fb5qhGg0TjJMvr74Fb5qhGg0TjJMvr74Fb5qhGg0LQJUvrYRC74/9XA0LQJUvrYRC74/9XA0LQJUvrYRC74/9XA0LQJUvrYRC74/9XA0qpxgvp207L0A4V40qpxgvp207L0A4V40qpxgvp207L0A4V40qpxgvp207L0A4V409Thrvl+qwL3qV2o09Thrvl+qwL3qV2o09Thrvl+qwL3qV2o09Thrvl+qwL3qV2o0l9xzvjs0kb2LrXM0l9xzvjs0kb2LrXM0l9xzvjs0kb2LrXM0l9xzvjs0kb2LrXM0gOh5vmctQ70INno0gOh5vmctQ70INno0gOh5vmctQ70INno0gOh5vmctQ70INno0/3x9vmIqyrziYV40/3x9vmIqyrziYV40/3x9vmIqyrziYV40/3x9vmIqyrziYV402st+vuCU1riwy1802st+vuCU1riwy1802st+vuCU1riwy1802st+vuCU1riwy180/Ih9vpWEyDzWbl40/Ih9vpWEyDzWbl40/Ih9vpWEyDzWbl40/Ih9vpWEyDzWbl40Wf95vgVoQj1PnFo0Wf95vgVoQj1PnFo0Wf95vgVoQj1PnFo0Wf95vgVoQj1PnFo0w/1zvonckD36HlQ0w/1zvonckD36HlQ0w/1zvonckD36HlQ0w/1zvonckD36HlQ0nGNrvtxgwD2W00o0nGNrvtxgwD2W00o0nGNrvtxgwD2W00o0nGNrvtxgwD2W00o0A89gvtF77D005j40A89gvtF77D005j40A89gvtF77D005j40A89gvtF77D005j40yjlUvs7/Cj66TTE0yjlUvs7/Cj66TTE0yjlUvs7/Cj66TTE0yjlUvs7/Cj66TTE0+mtMvuXsFT7qXSk0+mtMvuXsFT7qXSk0+mtMvuXsFT7qXSk0+mtMvuXsFT7qXSk0C2NEvksDID5uryA0C2NEvksDID5uryA0C2NEvksDID5uryA0C2NEvksDID5uryA0rXU8vpsDKT7ynxc0rXU8vpsDKT7ynxc0rXU8vpsDKT7ynxc0rXU8vpsDKT7ynxc0oQA1vtW/MD5AkQ80oQA1vtW/MD5AkQ80oQA1vtW/MD5AkQ80oQA1vtW/MD5AkQ80MlolvhoOPz68UP0zMlolvhoOPz68UP0zMlolvhoOPz68UP0zMlolvhoOPz68UP0zYN4Tvll+TD6kiNczYN4Tvll+TD6kiNczYN4Tvll+TD6kiNczYN4Tvll+TD6kiNczd4n4vc40Wz5shqUzd4n4vc40Wz5shqUzd4n4vc40Wz5shqUzd4n4vc40Wz5shqUziATEvbjEZz4ZhV0ziATEvbjEZz4ZhV0ziATEvbjEZz4ZhV0ziATEvbjEZz4ZhV0zSt2WvbzTbz7t4/cySt2WvbzTbz7t4/cySt2WvbzTbz7t4/cySt2WvbzTbz7t4/cy5KEZvYI1eD4/SBCy5KEZvYI1eD4/SBCy5KEZvYI1eD4/SBCy5KEZvYI1eD4/SBCyb2gVM5cTez5lEUqzb2gVM5cTez5lEUqzb2gVM5cTez5lEUqzb2gVM5cTez5lEUqz6qEZPYM1eD5VCLiz6qEZPYM1eD5VCLiz6qEZPYM1eD5VCLiz6qEZPYM1eD5VCLizSN2WPbzTbz4qBQS0SN2WPbzTbz4qBQS0SN2WPbzTbz4qBQS0SN2WPbzTbz4qBQS0lATEPbfEZz77aRy0lATEPbfEZz77aRy0lATEPbfEZz77aRy0lATEPbfEZz77aRy0lATEPbfEZz77aRy0eon4Pcw0Wz4Mxzm0eon4Pcw0Wz4Mxzm0eon4Pcw0Wz4Mxzm0eon4Pcw0Wz4Mxzm0Zd4TPll+TD5UEzS0Zd4TPll+TD5UEzS0Zd4TPll+TD5UEzS0Zd4TPll+TD5UEzS0Zd4TPll+TD5UEzS0MFolPhoOPz5a90a0MFolPhoOPz5a90a0MFolPhoOPz5a90a0MFolPhoOPz5a90a0oQA1PtW/MD4Orze0oQA1PtW/MD4Orze0oQA1PtW/MD4Orze0oQA1PtW/MD4Orze0sHU8PpoDKT7CvT+0sHU8PpoDKT7CvT+0sHU8PpoDKT7CvT+0sHU8PpoDKT7CvT+0EwRkPnTDOT4NGDO+EwRkPnTDOT4NGDO+8T1tPt75LT4V8y2+8T1tPt75LT4V8y2+4t51Pu8DIT7AuSu+4t51Pu8DIT7AuSu+OamBPiFgCD5ruyy+OamBPiFgCD5ruyy+I5KIPkUx3z0lPDO+I5KIPkUx3z0lPDO+BCiOPmDCqD2oUz2+BCiOPmDCqD2oUz2+UI+RPhhNYj24qUW+UI+RPhhNYj24qUW+hYCTPlMm6TwYz0q+hYCTPlMm6TwYz0q+FJCUPmeqErkEfky+FJCUPmeqErkEfky+hYCTPkJx67wYz0q+hYCTPkJx67wYz0q+UI+RPnhyY720qUW+UI+RPnhyY720qUW+AyiOPgxVqb2gUz2+AyiOPgxVqb2gUz2+IZKIPvLD370oPDO+IZKIPvLD370oPDO+OamBPnapCL5nuyy+OamBPnapCL5nuyy+2t51PkBNIb67uSu+2t51PkBNIb67uSu+8D1tPitDLr4V8y2+8D1tPitDLr4V8y2+DwRkPsoMOr4JGDO+DwRkPsoMOr4JGDO+K4JaPqE6RL7QlTu+K4JaPqE6RL7QlTu+pThRPnKSTL5gZka+pThRPnKSTL5gZka+kuE9PieqW74YE2G+kuE9PieqW74YE2G+kuApPrsya741dX2+kuApPrsya741dX2+DlMQPtjZfr7FQpG+DlMQPtjZfr7FQpG+VzfpPdQBir4bdai+VzfpPdQBir4bdai+VzfpPdQBir4bdai+wbazPdn5jr4Odai+wbazPdn5jr4Odai+nOI1PUEPk76Kdqi+nOI1PUEPk76Kdqi+RJW+tAOAlL7tdai+RJW+tAOAlL7tdai+V+M1vUMPk76Jdqi+V+M1vUMPk76Jdqi+HLezvdj5jr4Mdai+HLezvdj5jr4Mdai+rzfpvdIBir4Udai+rzfpvdIBir4Udai+rzfpvdIBir4Udai+OFMQvtDZfr68QpG+OFMQvtDZfr68QpG+ueApvrgya74pdX2+ueApvrgya74pdX2+uOE9viqqW74CE2G+uOE9viqqW74CE2G+yThRvnGSTL5KZka+yThRvnGSTL5KZka+UoJavps6RL60lTu+UoJavps6RL60lTu+LgRkvssMOr76FzO+LgRkvssMOr76FzO+Cz5tvihDLr728i2+Cz5tvihDLr728i2+/t51vj1NIb6fuSu+/t51vj1NIb6fuSu+T6mBvnWpCL5Guyy+T6mBvnWpCL5Guyy+MpKIvuDD370HPDO+MpKIvuDD370HPDO+EyiOvvdUqb1+Uz2+EyiOvvdUqb1+Uz2+YI+RvltyY72TqUW+YI+RvltyY72TqUW+lYCTvu5w67z1zkq+lYCTvu5w67z1zkq+IJCUvoaMErnmfUy+IJCUvoaMErnmfUy+loCTvo8m6Tz1zkq+loCTvo8m6Tz1zkq+XY+RvjVNYj2WqUW+XY+RvjVNYj2WqUW+ECiOvmjCqD2DUz2+ECiOvmjCqD2DUz2+L5KIvkgx3z0HPDO+L5KIvkgx3z0HPDO+SqmBvidgCD5Kuyy+SqmBvidgCD5Kuyy+At91vvUDIT6juSu+At91vvUDIT6juSu+DD5tvt75LT758i2+DD5tvt75LT758i2+MQRkvn7DOT7yFzO+MQRkvn7DOT7yFzO+TIJavk/xQz6tlTu+TIJavk/xQz6tlTu+wzhRviVJTD5NZka+wzhRviVJTD5NZka+tOE9vt1gWz4CE2G+tOE9vt1gWz4CE2G+ueApvmzpaj4gdX2+ueApvmzpaj4gdX2+NFMQvoyQfj66QpG+NFMQvoyQfj66QpG+qDfpvTLdiT4Sdai+qDfpvTLdiT4Sdai+qDfpvTLdiT4Sdai+GrezvTnVjj4Kdai+GrezvTnVjj4Kdai+O+M1vaDqkj6Bdqi+O+M1vaDqkj6Bdqi+1ciRtDGglD7rdai+1ciRtDGglD7rdai+muI1PaDqkj6Gdqi+muI1PaDqkj6Gdqi+w7azPTbVjj4Sdai+w7azPTbVjj4Sdai+XzfpPTDdiT4Zdai+XzfpPTDdiT4Zdai+XzfpPTDdiT4Zdai+FVMQPomQfj7DQpG+FVMQPomQfj7DQpG+mOApPmfpaj41dX2+mOApPmfpaj41dX2+leE9PthgWz4YE2G+leE9PthgWz4YE2G+qDhRPh9JTD5gZka+qDhRPh9JTD5gZka+MIJaPkXxQz7UlTu+MIJaPkXxQz7UlTu+uLIgvwAAAABsR0c/AAAAAAAAAAAAAIA/kY8dv+D2/j1XPEc/AAAAAAAAAAAAAIA/CU8Uv1jEeT4TGkc/AAAAAAAAAAAAAIA/Qk0FvxIZtT526kY/AAAAAAAAAAAAAIA/sGfivp0x5j4urkY/AAAAAAAAAAAAAIA/eqmxvhEkBz/wckY/AAAAAAAAAAAAAIA/SG90vnj+FT9NQEY/AAAAAAAAAAAAAIA/YQr5vT0bHz8SH0Y/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAG0uIj/hEkY/AAAAAAAAAAAAAIA/YQr5PT0bHz8SH0Y/AAAAAAAAAAAAAIA/SG90Pnj+FT9NQEY/AAAAAAAAAAAAAIA/eqmxPhEkBz/wckY/AAAAAAAAAAAAAIA/sGfiPp0x5j4urkY/AAAAAAAAAAAAAIA/CVIFP6cWtT7P50Y/AAAAAAAAAAAAAIA/CU8UP1jEeT4TGkc/AAAAAAAAAAAAAIA/kY8dP+D2/j1XPEc/AAAAAAAAAAAAAIA/uLIgPwAAAIBsR0c/AAAAAAAAAAAAAIA/kY8dP+D2/r1XPEc/AAAAAAAAAAAAAIA/CU8UP1jEeb4TGkc/AAAAAAAAAAAAAIA/CVIFP6cWtb7P50Y/AAAAAAAAAAAAAIA/sGfiPp0x5r4urkY/AAAAAAAAAAAAAIA/eqmxPhEkB7/wckY/AAAAAAAAAAAAAIA/SG90Pnj+Fb9NQEY/AAAAAAAAAAAAAIA/YQr5PT0bH78SH0Y/AAAAgG0uIr/hEkY/AAAAAAAAAAAAAIA/YQr5vT0bH78SH0Y/AAAAAAAAAAAAAIA/SG90vnj+Fb9NQEY/AAAAAAAAAAAAAIA/eqmxvhEkB7/wckY/AAAAAAAAAAAAAIA/sGfivp0x5r4urkY/AAAAAAAAAAAAAIA/Qk0FvxIZtb526kY/AAAAAAAAAAAAAIA/CU8Uv1jEeb4TGkc/AAAAAAAAAAAAAIA/kY8dv+D2/r1XPEc/AAAAAAAAAAAAAIA/yu96v26nSj4AAAAApZUdv2ck/j29O0c/AACAvwAAAIAAAAAAuLIgvwAAAABsR0c/ofxrv850xj4AAAAApmEUv0kleT6rGEc/J95Tv7yxDz8AAAAAlG0Fv7S8tD7L6UY/UKgzv/xeNj8AAAAAtcPiviPW5T5qrkY/lL8Mvw7WVT8AAAAAwwOyvr4IBz9PcUY/am7BvhEHbT8AAAAA7Qp1vlrwFT/4PkY/FexEvsM4ez8AAAAATqn5vboVHz9fIEY/AAAAAG0uIj/hEkY/AAAAAAAAgD8AAACATqn5PboVHz9fIEY/FexEPsM4ez8AAACA7Qp1PlrwFT/4PkY/am7BPhEHbT8AAACAKwayPgQEBz/9c0Y/lL8MPw7WVT8AAACAtcPiPiPW5T5qrkY/UKgzP/xeNj8AAACAlG0FP7S8tD7L6UY/J95TP7yxDz8AAACApmEUP0kleT6rGEc/ofxrP850xj4AAACApZUdP2ck/j29O0c/yu96P26nSj4AAACAuLIgPwAAAIBsR0c/AACAPwAAAIAAAACApZUdP2ck/r29O0c/yu96P26nSr4AAACApmEUP0kleb6rGEc/ofxrP850xr4AAACAlG0FP7S8tL7L6UY/J95TP7yxD78AAACAtcPiPiPW5b5qrkY/UKgzP/xeNr8AAACAKwayPgQEB7/9c0Y/lL8MPw7WVb8AAACA7Qp1PlrwFb/4PkY/am7BPhEHbb8AAACATqn5PboVH79fIEY/FexEPsM4e78AAACAAAAAgAAAgL8AAACAAAAAgG0uIr/hEkY/FexEvsM4e78AAAAATqn5vboVH79fIEY/am7BvhEHbb8AAAAA7Qp1vlrwFb/4PkY/lL8Mvw7WVb8AAAAAwwOyvr4IB79PcUY/UKgzv/xeNr8AAAAAtcPiviPW5b5qrkY/J95Tv7yxD78AAAAAlG0Fv7S8tL7L6UY/ofxrv850xr4AAAAApmEUv0kleb6rGEc/yu96v26nSr4AAAAApZUdv2ck/r29O0c/yu96v26nSj4AAAAAkVE/v/27Gj73oyU/AACAvwAAAIAAAAAAoiNDvwAAAIBdsyU/ofxrv850xj4AAAAAUQY0v3+Olz7CeyU/J95Tv7yxDz8AAAAAPcIhv1aw2z58PSU/UKgzv/xeNj8AAAAA50oJv56LCz9V9yQ/lL8Mvw7WVT8AAAAAl1bXvjDIIz+OrSQ/am7BvhEHbT8AAAAAQR6UvtOtNT9bcyQ/FexEvsM4ez8AAAAAE9gWvkitQD/qSCQ/AAAAAI5hRD8XOiQ/AAAAAAAAgD8AAACAE9gWPkitQD/qSCQ/FexEPsM4ez8AAACAQR6UPtOtNT9bcyQ/am7BPhEHbT8AAACAl1bXPjDIIz+OrSQ/lL8MPw7WVT8AAACA50oJP56LCz9V9yQ/UKgzP/xeNj8AAACAPcIhP1aw2z58PSU/J95TP7yxDz8AAACAUQY0P3+Olz7CeyU/ofxrP850xj4AAACAkVE/P/27Gj73oyU/yu96P26nSj4AAACAoiNDPwAAAABdsyU/AACAPwAAAIAAAACAkVE/P/27Gr73oyU/yu96P26nSr4AAACAUQY0P3+Ol77CeyU/ofxrP850xr4AAACAPcIhP1aw2758PSU/J95TP7yxD78AAACA50oJP56LC79V9yQ/UKgzP/xeNr8AAACAl1bXPjDII7+OrSQ/lL8MPw7WVb8AAACAQR6UPtOtNb9bcyQ/am7BPhEHbb8AAACAE9gWPkitQL/qSCQ/FexEPsM4e78AAACAAAAAgAAAgL8AAACAAAAAgI5hRL8XOiQ/FexEvsM4e78AAAAAE9gWvkitQL/qSCQ/am7BvhEHbb8AAAAAPhKUviqvNb+SdCQ/lL8Mvw7WVb8AAAAAl1bXvjDII7+OrSQ/UKgzv/xeNr8AAAAA50oJv56LC79V9yQ/J95Tv7yxD78AAAAAPcIhv1aw2758PSU/ofxrv850xr4AAAAAUQY0v3+Ol77CeyU/yu96v26nSr4AAAAAkVE/v/27Gr73oyU/yu96v26nSj4AAAAAalc/v49SGj5coyU/AACAvwAAAAAAAAAAoiNDvwAAAABdsyU/ofxrv850xj4AAAAAbhg0v4w+lz5WeiU/J95Tv7yxDz8AAAAAad4hvz1X2z58PyU/UKgzv/xeNj8AAAAA+3gJv/JdCz+T9yQ/lL8Mvw7WVT8AAAAAuLPXvnioIz+criQ/am7BvhEHbT8AAAAAr2uUvj2fNT8EciQ/FexEvsM4ez8AAAAAhiIXvvCnQD/oSiQ/AAAAAI5hRD8XOiQ/AAAAgAAAgD8AAAAAASUXPhmrQD8NRyQ/FexEPsM4ez8AAACAr2uUPj2fNT8EciQ/am7BPhEHbT8AAACAuLPXPnioIz+criQ/lL8MPw7WVT8AAACA+3gJP/JdCz+T9yQ/UKgzP/xeNj8AAACAad4hPz1X2z58PyU/J95TP7yxDz8AAACAbhg0P4w+lz5WeiU/ofxrP850xj4AAACAalc/P49SGj5coyU/yu96P26nSj4AAACAoiNDPwAAAABdsyU/AACAPwAAAIAAAACAalc/P49SGr5coyU/yu96P26nSr4AAACAbhg0P4w+l75WeiU/ofxrP850xr4AAACAad4hPz1X2758PyU/J95TP7yxD78AAACA+3gJP/JdC7+T9yQ/UKgzP/xeNr8AAACAuLPXPnioI7+criQ/lL8MPw7WVb8AAACAr2uUPj2fNb8EciQ/am7BPhEHbb8AAACAASUXPhmrQL8NRyQ/FexEPsM4e78AAACAAAAAgAAAgL8AAACAAAAAgI5hRL8XOiQ/FexEvsM4e78AAAAAASUXvhmrQL8NRyQ/am7BvhEHbb8AAAAArV+UvpagNb88cyQ/lL8Mvw7WVb8AAAAAuLPXvnioI7+criQ/UKgzv/xeNr8AAAAA+3gJv/JdC7+T9yQ/J95Tv7yxD78AAAAAad4hvz1X2758PyU/ofxrv850xr4AAAAAbhg0v4w+l75WeiU/yu96v26nSr4AAAAAalc/v49SGr5coyU/yu96v26nSj4AAAAA6PtFv8gLID4FSB0/AACAvwAAAAAAAAAAYvBJvwAAAACqVx0/ofxrv850xj4AAAAArUo6v3fTnD6NGx0/J95Tv7yxDz8AAAAA5F4nvx5G4z7z3xw/UKgzv/xeNj8AAAAAlAwOv2FaED/jlhw/lL8Mvw7WVT8AAAAAY8XevrJrKT+zSRw/am7BvhEHbT8AAAAADDCZvh/tOz8JDhw/FexEvsM4ez8AAAAAew4cvuJERz8p5xs/AAAAALAWSz8R2xs/AAAAgAAAgD8AAAAAew4cPuJERz8p5xs/FexEPsM4ez8AAACADDCZPh/tOz8JDhw/am7BPhEHbT8AAACAY8XePrJrKT+zSRw/lL8MPw7WVT8AAACAlAwOP2FaED/jlhw/UKgzP/xeNj8AAACA5F4nPx5G4z7z3xw/J95TP7yxDz8AAACArUo6P3fTnD6NGx0/ofxrP850xj4AAACA6PtFP8gLID4FSB0/yu96P26nSj4AAACAYvBJPwAAAICqVx0/AACAPwAAAAAAAACA6PtFP8gLIL4FSB0/yu96P26nSr4AAACArUo6P3fTnL6NGx0/ofxrP850xr4AAACA5F4nPx5G477z3xw/J95TP7yxD78AAACAlAwOP2FaEL/jlhw/UKgzP/xeNr8AAACAY8XePrJrKb+zSRw/lL8MPw7WVb8AAACADDCZPh/tO78JDhw/am7BPhEHbb8AAACAew4cPuJER78p5xs/FexEPsM4e78AAACAAAAAgAAAgL8AAACAAAAAALAWS78R2xs/FexEvsM4e78AAAAAew4cvuJER78p5xs/am7BvhEHbb8AAAAADDCZvh/tO78JDhw/lL8Mvw7WVb8AAAAAY8XevrJrKb+zSRw/UKgzv/xeNr8AAAAAlAwOv2FaEL/jlhw/J95Tv7yxD78AAAAA5F4nvx5G477z3xw/ofxrv850xr4AAAAArUo6v3fTnL6NGx0/yu96v26nSr4AAAAA6PtFv8gLIL4FSB0/yu96v26nSj4AAACASP5Fvw+/Hz7oSR0/AACAvwAAAAAAAACAYvBJvwAAAACqVx0/ofxrv850xj4AAACAmVk6v1iGnD4UHR0/J95Tv7yxDz8AAAAANHsnvzbt4j7q4Rw/UKgzv/xeNj8AAAAAFTQOv0AzED8Xlxw/lL8Mvw7WVT8AAAAAniLfvg1MKT+8Shw/am7BvhEHbT8AAAAAR4CZvmjbOz+nDxw/FexEvsM4ez8AAAAAaV4cvvc/Rz9x6Bs/AAAAALAWSz8R2xs/AAAAAAAAgD8AAACAaV4cPvc/Rz9x6Bs/FexEPsM4ez8AAACAR4CZPmjbOz+nDxw/am7BPhEHbT8AAACAniLfPg1MKT+8Shw/lL8MPw7WVT8AAACAFTQOP0AzED8Xlxw/UKgzP/xeNj8AAACA834nP2rp4j5K3xw/J95TP7yxDz8AAACAmVk6P1iGnD4UHR0/ofxrP850xj4AAACASP5FPw+/Hz7oSR0/yu96P26nSj4AAACAYvBJPwAAAICqVx0/AACAPwAAAIAAAACASP5FPw+/H77oSR0/yu96P26nSr4AAACAmVk6P1iGnL4UHR0/ofxrP850xr4AAACANHsnPzbt4r7q4Rw/J95TP7yxD78AAACAFTQOP0AzEL8Xlxw/UKgzP/xeNr8AAACAniLfPg1MKb+8Shw/lL8MPw7WVb8AAACAR4CZPmjbO7+nDxw/am7BPhEHbb8AAACAaV4cPvc/R79x6Bs/FexEPsM4e78AAACAAAAAgAAAgL8AAACAAAAAALAWS78R2xs/FexEvsM4e78AAAAAaV4cvvc/R79x6Bs/am7BvhEHbb8AAAAAR4CZvmjbO7+nDxw/lL8Mvw7WVb8AAAAAniLfvg1MKb+8Shw/UKgzv/xeNr8AAAAAFTQOv0AzEL8Xlxw/J95Tv7yxD78AAAAANHsnvzbt4r7q4Rw/ofxrv850xr4AAACAmVk6v1iGnL4UHR0/yu96v26nSr4AAACASP5Fvw+/H77oSR0/eCh1vzsNRj4qblo+exp6vwAAAACeg1o+h49mv5jzwT5hHlo+rQFPv+lxDD/vmlk+1osvv41CMj+K/lg+jYsJv7cEUT/Dd1g+8Qe9vtS0Zz9Z9lc+8mpAvlmXdT/eqVc+AAAAAJxDej/8jFc+8mpAPlmXdT/eqVc+8Qe9PtS0Zz9Z9lc+jYsJP7cEUT/Dd1g+1osvP41CMj+K/lg+rQFPP+lxDD/vmlk+h49mP5jzwT5hHlo+eCh1PzsNRj4qblo+exp6PwAAAICeg1o+eCh1PzsNRr4qblo+h49mP5jzwb5hHlo+rQFPP+lxDL/vmlk+1osvP41CMr+K/lg+jYsJP7cEUb/Dd1g+8Qe9PtS0Z79Z9lc+8mpAPlmXdb/eqVc+AAAAAJxDer/8jFc+8mpAvlmXdb/eqVc+8Qe9vtS0Z79Z9lc+jYsJv7cEUb/Dd1g+1osvv41CMr+K/lg+rQFPv+lxDL/vmlk+h49mv5jzwb5hHlo+eCh1vzsNRr4qblo+YV1rv5cNPj51j7E+NRhwvwAAAACAqLE+UWNdv5gpuj4QTrE+CtJGv7PXBj/a57A+OKcovwcwKz+hfLA+Fi4Ev7LKSD8FCbA+TbS1vj+jXj+xqa8+KAs5vtkDbD/paq8+AAAAADaGcD9YUa8+KAs5PtkDbD/paq8+TbS1Pj+jXj+xqa8+Fi4EP7LKSD8FCbA+OKcoPwcwKz+hfLA+pNRGPwXVBj9V5LA+UWNdP5gpuj4QTrE+YV1rP5cNPj51j7E+NRhwPwAAAICAqLE+YV1rP5cNPr51j7E+UWNdP5gpur4QTrE+pNRGPwXVBr9V5LA+OKcoPwcwK7+hfLA+Fi4EP7LKSL8FCbA+TbS1Pj+jXr+xqa8+KAs5PtkDbL/paq8+AAAAADaGcL9YUa8+KAs5vtkDbL/paq8+TbS1vj+jXr+xqa8+Fi4Ev7LKSL8FCbA+OKcovwcwK7+hfLA+CtJGv7PXBr/a57A+UWNdv5gpur4QTrE+YV1rv5cNPr51j7E+IKtwv09BQj4IAJE+Gbkov3B+CD7cez0/6YJ1vwAAAADRDZE+TxQsvwAAAADDiT0/tWFiv4tCvj4zvpA+3csev+m7hT5JVj0/pUtLvw3PCT97cJA+frcOv9fjwT7mID0/NXMsv331Lj9bCJA+LmHyvopf9j464Dw/2SQHv0E2TT85q48+PCe+viejED8Hnjw/j8y5vpqGYz8HW48+O9GCvu98ID/7ajw/mSI9vsk0cT8UG48+CjcFvgU7Kj8NRzw/AAAAAIyCLT+4Ojw/AAAAACXOdT+hDI8+CjcFPgU7Kj8NRzw/mSI9Psk0cT8UG48+O9GCPu98ID/7ajw/4825PjqIYz/yTo8+PCe+PiejED8Hnjw/2SQHP0E2TT85q48+LmHyPopf9j464Dw/NXMsP331Lj9bCJA+frcOP9fjwT7mID0/pUtLPw3PCT97cJA+3cseP+m7hT5JVj0/tWFiP4tCvj4zvpA+GbkoP3B+CD7cez0/IKtwP09BQj4IAJE+TxQsPwAAAIDDiT0/6YJ1PwAAAIDRDZE+GbkoP3B+CL7cez0/IKtwP09BQr4IAJE+3cseP+m7hb5JVj0/tWFiP4tCvr4zvpA+frcOP9fjwb7mID0/pUtLPw3PCb97cJA+LmHyPopf9r464Dw/NXMsP331Lr9bCJA+PCe+PiejEL8Hnjw/2SQHP0E2Tb85q48+O9GCPu98IL/7ajw/4825PjqIY7/yTo8+CjcFPgU7Kr8NRzw/mSI9Psk0cb8UG48+AAAAgCXOdb+hDI8+AAAAAIyCLb+4Ojw/mSI9vsk0cb8UG48+CjcFvgU7Kr8NRzw/4825vjqIY7/yTo8+O9GCvu98IL/7ajw/2SQHv0E2Tb85q48+PCe+viejEL8Hnjw/NXMsv331Lr9bCJA+LmHyvopf9r464Dw/pUtLvw3PCb97cJA+frcOv9fjwb7mID0/tWFiv4tCvr4zvpA+3csev+m7hb5JVj0/IKtwv09BQr4IAJE+Gbkov3B+CL7cez0/yu96v26nSj4AAAAAZrsov3AXCD5xfj0/AACAvwAAAAAAAAAATxQsvwAAAADDiT0/ofxrv850xj4AAAAAS9oev2BuhT7dVz0/J95Tv7yxDz8AAAAAIdkOvyp8wT4MIj0/UKgzv/xeNj8AAAAAFLPyvhYH9j7B4jw/lL8Mvw7WVT8AAAAAEIS+vjODED8Ynzw/am7BvhEHbT8AAAAA7x6DvqxuID+haTw/FexEvsM4ez8AAAAAYqAFvhc1Kj+9Rzw/AAAAAIyCLT+4Ojw/AAAAAAAAgD8AAAAAYqAFPhc1Kj+9Rzw/FexEPsM4ez8AAACA7x6DPqxuID+haTw/am7BPhEHbT8AAACAEIS+PjODED8Ynzw/lL8MPw7WVT8AAACAFLPyPhYH9j7B4jw/UKgzP/xeNj8AAACAIdkOPyp8wT4MIj0/J95TP7yxDz8AAACAS9oeP2BuhT7dVz0/ofxrP850xj4AAACAZrsoP3AXCD5xfj0/yu96P26nSj4AAACATxQsPwAAAIDDiT0/AACAPwAAAIAAAACAZrsoP3AXCL5xfj0/yu96P26nSr4AAACAS9oeP2Buhb7dVz0/ofxrP850xr4AAACAIdkOPyp8wb4MIj0/J95TP7yxD78AAACAFLPyPhYH9r7B4jw/UKgzP/xeNr8AAACAEIS+PjODEL8Ynzw/lL8MPw7WVb8AAACA7x6DPqxuIL+haTw/am7BPhEHbb8AAACAYqAFPhc1Kr+9Rzw/FexEPsM4e78AAACAAAAAgAAAgL8AAAAAAAAAAIyCLb+4Ojw/FexEvsM4e78AAAAAYqAFvhc1Kr+9Rzw/am7BvhEHbb8AAAAA7x6DvqxuIL+haTw/lL8Mvw7WVb8AAAAAEIS+vjODEL8Ynzw/UKgzv/xeNr8AAAAAFLPyvhYH9r7B4jw/J95Tv7yxD78AAAAAIdkOvyp8wb4MIj0/ofxrv850xr4AAAAAS9oev2Buhb7dVz0/yu96v26nSr4AAAAAZrsov3AXCL5xfj0/yu96v26nSj4AAAAAdz3fvQJ8pTwKbH6/AACAvwAAAAAAAACADF3cvTsSg7p/g36/ofxrv850xj4AAAAAeQjfvRm5Lz2FPX6/J95Tv7yxDz8AAAAAZCPbvT3hiz3U7X2/UKgzv/xeNj8AAAAAqSvUvUF/yD3YYn2/lL8Mvw7WVT8AAAAARMnDvWYCCT7Zg3y/am7BvhEHbT8AAAAADyupvaNaNT5zEHu/FexEvsM4ez8AAAAAMFJjvaG8gT67PHe/wu2nvPyYpj4OA3K/AAAAAAAAgD8AAAAA2FKFPcO9AD/5pFy/FexEPsM4ez8AAACAzW58Pi6gQT/oHhu/2rDDPqKMbD9teyU8FOnVPq9LBj/l5T0/bpsFPz8XWD9bs/s9Hw3ePit59j4Q/kI/UKgzP/xeNj8AAACAmxfCPm9IjD4vRWI/J95TP7yxDz8AAACAhDG7PuF7JT5LqGo/ofxrP850xj4AAACAoo++PjFInT0ay2w/yu96P26nSj4AAACAlkDEPsNZhrvhcWw/AACAPwAAAIAAAACASYvbPrr6y71e3GU/yu96P26nSr4AAACAntYDP8SfeL54dFI/ofxrP850xr4AAACAb2VFP2IGDr/j/p8+7joePwxpPb/6+4e++3k0P+hlNb9WwfU8c0a2Pg+JE78gUTy/lL8MPw7WVb8AAACArm74PePWuL4DtWy/am7BPhEHbb8AAACA3b4fPfCyjL4N8XW/FexEPsM4e78AAACANPlCvGKwVL4HZnq/AAAAgAAAgL8AAAAAFexEvsM4e78AAAAA7XUcvYLcMb5H63u/am7BvhEHbb8AAAAAvbt8vSjcCr6ZJH2/lL8Mvw7WVb8AAAAASBCcvbrU3r06u32/UKgzv/xeNr8AAAAAvsqyvdylrL2aG36/J95Tv7yxD78AAAAABiXCveyIfb2hWn6/ofxrv850xr4AAAAAiTrOvbuFJ73Ge36/yu96v26nSr4AAACAcajXvaTarLz4hH6/am7BvhEHbT8AAAAAAAAAgAAAAIAAAIC/am7BvhEHbT8AAAAAAAAAAAAAAAAAAIA/lL8Mvw7WVT8AAAAAAAAAAAAAAIAAAIA/lL8Mvw7WVT8AAAAAAAAAgAAAAAAAAIC/AAAAgAAAAAAAAIC/UKgzP/xeNr8AAACAAAAAAAAAAIAAAIA/UKgzP/xeNr8AAACAAAAAAAAAAAAAAIA/J95TP7yxD78AAACAAAAAgAAAAIAAAIC/J95TP7yxD78AAACAFexEvsM4ez8AAAAAAAAAgAAAAAAAAIC/FexEvsM4ez8AAAAAAAAAAAAAAIAAAIA/AAAAgAAAAAAAAIC/lL8MPw7WVb8AAACAAAAAAAAAAIAAAIA/lL8MPw7WVb8AAACAAAAAgAAAAIAAAIC/AAAAAAAAgD8AAAAAAAAAAAAAAIAAAIA/AAAAAAAAgD8AAAAAAAAAgAAAAIAAAIC/am7BPhEHbb8AAACAAAAAAAAAAIAAAIA/am7BPhEHbb8AAACAAAAAgAAAAIAAAIC/FexEPsM4ez8AAACAAAAAAAAAAAAAAIA/FexEPsM4ez8AAACAAAAAgAAAAAAAAIC/FexEPsM4e78AAACAAAAAAAAAAIAAAIA/FexEPsM4e78AAACAAAAAgAAAAAAAAIC/am7BPhEHbT8AAACAAAAAAAAAAAAAAIA/am7BPhEHbT8AAACAAAAAgAAAgL8AAAAAAAAAgAAAAAAAAIC/AAAAgAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAgAAAAIAAAIC/lL8MPw7WVT8AAACAAAAAAAAAAAAAAIA/lL8MPw7WVT8AAACAFexEvsM4e78AAAAAAAAAgAAAAAAAAIC/FexEvsM4e78AAAAAAAAAAAAAAIAAAIA/AAAAgAAAAIAAAIC/UKgzP/xeNj8AAACAAAAAAAAAAAAAAIA/UKgzP/xeNj8AAACAam7BvhEHbb8AAAAAAAAAgAAAAAAAAIC/am7BvhEHbb8AAAAAAAAAAAAAAIAAAIA/AAAAgAAAAAAAAIC/J95TP7yxDz8AAACAAAAAAAAAAAAAAIA/J95TP7yxDz8AAACAlL8Mvw7WVb8AAAAAAAAAgAAAAIAAAIC/lL8Mvw7WVb8AAAAAAAAAAAAAAIAAAIA/AAAAgAAAAAAAAIC/ofxrP850xj4AAACAAAAAAAAAAIAAAIA/ofxrP850xj4AAACAyu96v26nSj4AAAAAAAAAgAAAAIAAAIC/yu96v26nSj4AAAAAAAAAAAAAAAAAAIA/AACAvwAAAAAAAACAAAAAAAAAAIAAAIA/AACAvwAAAIAAAAAAAAAAgAAAAAAAAIC/UKgzv/xeNr8AAAAAAAAAgAAAAIAAAIC/UKgzv/xeNr8AAAAAAAAAAAAAAIAAAIA/AAAAgAAAAAAAAIC/yu96P26nSj4AAACAAAAAAAAAAIAAAIA/yu96P26nSj4AAACAofxrv850xj4AAAAAAAAAgAAAAAAAAIC/ofxrv850xj4AAAAAAAAAAAAAAIAAAIA/J95Tv7yxD78AAAAAAAAAgAAAAIAAAIC/J95Tv7yxD78AAAAAAAAAAAAAAIAAAIA/AAAAgAAAAAAAAIC/AACAPwAAAIAAAACAAAAAAAAAAAAAAIA/AACAPwAAAIAAAACAJ95Tv7yxDz8AAAAAAAAAgAAAAAAAAIC/J95Tv7yxDz8AAAAAAAAAAAAAAIAAAIA/ofxrv850xr4AAAAAAAAAgAAAAAAAAIC/ofxrv850xr4AAAAAAAAAAAAAAIAAAIA/AAAAgAAAAAAAAIC/yu96P26nSr4AAACAAAAAAAAAAAAAAIA/yu96P26nSr4AAACAUKgzv/xeNj8AAAAAAAAAgAAAAAAAAIC/UKgzv/xeNj8AAAAAAAAAAAAAAIAAAIA/yu96v26nSr4AAAAAAAAAgAAAAAAAAIC/yu96v26nSr4AAACAAAAAAAAAAIAAAIA/AAAAgAAAAIAAAIC/ofxrP850xr4AAACAAAAAAAAAAAAAAIA/ofxrP850xr4AAACAam7BvhEHbT8AAAAAAAAAAAAAAAAAAIA/am7BvhEHbT8AAAAAAAAAgAAAAIAAAIC/lL8Mvw7WVT8AAAAAAAAAgAAAAAAAAIC/lL8Mvw7WVT8AAAAAAAAAAAAAAIAAAIA/AAAAAAAAAIAAAIA/UKgzP/xeNr8AAACAAAAAgAAAAAAAAIC/UKgzP/xeNr8AAACAAAAAgAAAAIAAAIC/J95TP7yxD78AAACAAAAAAAAAAIAAAIA/J95TP7yxD78AAACAFexEvsM4ez8AAAAAAAAAAAAAAIAAAIA/FexEvsM4ez8AAAAAAAAAgAAAAAAAAIC/AAAAAAAAAIAAAIA/lL8MPw7WVb8AAACAAAAAgAAAAIAAAIC/lL8MPw7WVb8AAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAAAAgAAAAAAAAIC/AAAAAAAAgD8AAACAAAAAAAAAAAAAAIA/am7BPhEHbb8AAACAAAAAgAAAAAAAAIC/am7BPhEHbb8AAACAAAAAAAAAAIAAAIA/FexEPsM4ez8AAACAAAAAgAAAAIAAAIC/FexEPsM4ez8AAACAAAAAAAAAAAAAAIA/FexEPsM4e78AAACAAAAAgAAAAAAAAIC/FexEPsM4e78AAACAAAAAAAAAAIAAAIA/am7BPhEHbT8AAACAAAAAgAAAAIAAAIC/am7BPhEHbT8AAACAAAAAgAAAgL8AAACAAAAAAAAAAIAAAIA/AAAAgAAAgL8AAACAAAAAgAAAAIAAAIC/AAAAAAAAAAAAAIA/lL8MPw7WVT8AAACAAAAAgAAAAAAAAIC/lL8MPw7WVT8AAACAFexEvsM4e78AAAAAAAAAAAAAAAAAAIA/FexEvsM4e78AAAAAAAAAgAAAAAAAAIC/AAAAAAAAAAAAAIA/UKgzP/xeNj8AAACAAAAAgAAAAAAAAIC/UKgzP/xeNj8AAACAam7BvhEHbb8AAAAAAAAAAAAAAIAAAIA/am7BvhEHbb8AAAAAAAAAgAAAAIAAAIC/AAAAAAAAAIAAAIA/J95TP7yxDz8AAACAAAAAgAAAAAAAAIC/J95TP7yxDz8AAACAlL8Mvw7WVb8AAAAAAAAAAAAAAIAAAIA/lL8Mvw7WVb8AAAAAAAAAgAAAAIAAAIC/AAAAAAAAAIAAAIA/ofxrP850xj4AAACAAAAAgAAAAAAAAIC/ofxrP850xj4AAACAyu96v26nSj4AAAAAAAAAAAAAAAAAAIA/yu96v26nSj4AAAAAAAAAgAAAAIAAAIC/AACAvwAAAIAAAAAAAAAAgAAAAIAAAIC/AACAvwAAAIAAAAAAAAAAAAAAAIAAAIA/UKgzv/xeNr8AAAAAAAAAAAAAAIAAAIA/UKgzv/xeNr8AAAAAAAAAgAAAAAAAAIC/AAAAAAAAAIAAAIA/yu96P26nSj4AAACAAAAAgAAAAAAAAIC/yu96P26nSj4AAACAofxrv850xj4AAAAAAAAAgAAAAIAAAIA/ofxrv850xj4AAAAAAAAAgAAAAAAAAIC/J95Tv7yxD78AAAAAAAAAAAAAAIAAAIA/J95Tv7yxD78AAAAAAAAAgAAAAAAAAIC/AAAAAAAAAIAAAIA/AACAPwAAAIAAAACAAAAAgAAAAAAAAIC/AACAPwAAAIAAAACAJ95Tv7yxDz8AAAAAAAAAAAAAAAAAAIA/J95Tv7yxDz8AAAAAAAAAgAAAAAAAAIC/ofxrv850xr4AAAAAAAAAAAAAAIAAAIA/ofxrv850xr4AAAAAAAAAgAAAAIAAAIC/AAAAAAAAAIAAAIA/yu96P26nSr4AAACAAAAAgAAAAIAAAIC/yu96P26nSr4AAACAUKgzv/xeNj8AAAAAAAAAgAAAAIAAAIA/UKgzv/xeNj8AAAAAAAAAgAAAAAAAAIC/yu96v26nSr4AAAAAAAAAAAAAAIAAAIA/yu96v26nSr4AAAAAAAAAgAAAAAAAAIC/AAAAAAAAAAAAAIA/ofxrP850xr4AAACAAAAAgAAAAIAAAIC/ofxrP850xr4AAACAam7BvhEHbT8AAAAAAAAAgAAAAIAAAIC/am7BvhEHbT8AAAAAAAAAAAAAAAAAAIA/lL8Mvw7WVT8AAAAAAAAAAAAAAIAAAIA/lL8Mvw7WVT8AAAAAAAAAgAAAAAAAAIC/AAAAgAAAAAAAAIC/UKgzP/xeNr8AAACAAAAAAAAAAIAAAIA/UKgzP/xeNr8AAACAAAAAAAAAAIAAAIA/J95TP7yxD78AAACAAAAAgAAAAAAAAIC/J95TP7yxD78AAACAFexEvsM4ez8AAAAAAAAAgAAAAAAAAIC/FexEvsM4ez8AAAAAAAAAAAAAAIAAAIA/AAAAgAAAAIAAAIC/lL8MPw7WVb8AAACAAAAAAAAAAIAAAIA/lL8MPw7WVb8AAACAAAAAgAAAAAAAAIC/AAAAAAAAgD8AAAAAAAAAAAAAAIAAAIA/AAAAAAAAgD8AAAAAAAAAgAAAAAAAAIC/am7BPhEHbb8AAACAAAAAAAAAAIAAAIA/am7BPhEHbb8AAACAAAAAgAAAAIAAAIC/FexEPsM4ez8AAACAAAAAAAAAAIAAAIA/FexEPsM4ez8AAACAAAAAgAAAAIAAAIC/FexEPsM4e78AAACAAAAAAAAAAAAAAIA/FexEPsM4e78AAACAAAAAgAAAAIAAAIC/am7BPhEHbT8AAACAAAAAAAAAAAAAAIA/am7BPhEHbT8AAACAAAAAgAAAgL8AAAAAAAAAgAAAAIAAAIC/AAAAgAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAgAAAAAAAAIC/lL8MPw7WVT8AAACAAAAAAAAAAAAAAIA/lL8MPw7WVT8AAACAFexEvsM4e78AAAAAAAAAgAAAAIAAAIC/FexEvsM4e78AAAAAAAAAAAAAAAAAAIA/AAAAgAAAAAAAAIC/UKgzP/xeNj8AAACAAAAAAAAAAAAAAIA/UKgzP/xeNj8AAACAam7BvhEHbb8AAAAAAAAAgAAAAAAAAIC/am7BvhEHbb8AAAAAAAAAAAAAAIAAAIA/AAAAgAAAAAAAAIC/J95TP7yxDz8AAACAAAAAAAAAAAAAAIA/J95TP7yxDz8AAACAlL8Mvw7WVb8AAAAAAAAAgAAAAIAAAIC/lL8Mvw7WVb8AAAAAAAAAAAAAAIAAAIA/AAAAgAAAAAAAAIC/ofxrP850xj4AAACAAAAAAAAAAIAAAIA/ofxrP850xj4AAACAyu96v26nSj4AAAAAAAAAgAAAAIAAAIC/yu96v26nSj4AAAAAAAAAAAAAAAAAAIA/AACAvwAAAIAAAACAAAAAAAAAAIAAAIA/AACAvwAAAAAAAACAAAAAgAAAAAAAAIC/UKgzv/xeNr8AAAAAAAAAgAAAAAAAAIC/UKgzv/xeNr8AAAAAAAAAAAAAAIAAAIA/AAAAgAAAAAAAAIC/yu96P26nSj4AAACAAAAAAAAAAIAAAIA/yu96P26nSj4AAACAofxrv850xj4AAAAAAAAAgAAAAAAAAIC/ofxrv850xj4AAAAAAAAAAAAAAIAAAIA/J95Tv7yxD78AAAAAAAAAgAAAAAAAAIC/J95Tv7yxD78AAAAAAAAAAAAAAIAAAIA/AAAAgAAAAAAAAIC/AACAPwAAAIAAAACAAAAAAAAAAAAAAIA/AACAPwAAAIAAAACAJ95Tv7yxDz8AAAAAAAAAgAAAAAAAAIC/J95Tv7yxDz8AAAAAAAAAAAAAAIAAAIA/ofxrv850xr4AAAAAAAAAgAAAAIAAAIC/ofxrv850xr4AAAAAAAAAAAAAAIAAAIA/AAAAgAAAAIAAAIC/yu96P26nSr4AAACAAAAAAAAAAAAAAIA/yu96P26nSr4AAACAUKgzv/xeNj8AAACAAAAAgAAAAAAAAIC/UKgzv/xeNj8AAACAAAAAAAAAAIAAAIA/yu96v26nSr4AAAAAAAAAgAAAAAAAAIC/yu96v26nSr4AAAAAAAAAAAAAAIAAAIA/AAAAgAAAAIAAAIC/ofxrP850xr4AAACAAAAAAAAAAAAAAIA/ofxrP850xr4AAACAAAAAgAAAAIAAAIC/ofxrP850xr4AAACAAAAAAAAAAAAAAIA/J95TP7yxD78AAACAyu96v26nSr4AAACAAAAAgAAAAAAAAIC/AACAvwAAAAAAAAAAAAAAAAAAAIAAAIA/UKgzv/xeNj8AAAAAAAAAgAAAAAAAAIC/lL8Mvw7WVT8AAACAAAAAAAAAAAAAAIA/AAAAgAAAAAAAAIC/yu96P26nSr4AAACAofxrv850xr4AAAAAAAAAgAAAAAAAAIC/J95Tv7yxDz8AAAAAAAAAgAAAAAAAAIC/AAAAgAAAAAAAAIC/AACAPwAAAIAAAACAJ95Tv7yxD78AAAAAAAAAgAAAAIAAAIC/ofxrv850xj4AAACAAAAAgAAAAAAAAIC/AAAAgAAAAAAAAIC/yu96P26nSj4AAACAUKgzv/xeNr8AAAAAAAAAgAAAAIAAAIC/yu96v26nSj4AAACAAAAAgAAAAIAAAIC/AAAAgAAAAAAAAIC/ofxrP850xj4AAACAlL8Mvw7WVb8AAAAAAAAAgAAAAIAAAIC/AAAAgAAAAAAAAIC/J95TP7yxDz8AAACAam7BvhEHbb8AAAAAAAAAgAAAAAAAAIC/AAAAgAAAAIAAAIC/UKgzP/xeNj8AAACAFexEvsM4e78AAAAAAAAAgAAAAAAAAIC/AAAAgAAAAIAAAIC/lL8MPw7WVT8AAACAAAAAgAAAgL8AAACAAAAAgAAAAAAAAIC/AAAAgAAAAAAAAIC/am7BPhEHbT8AAACAAAAAgAAAAAAAAIC/FexEPsM4e78AAACAAAAAgAAAAIAAAIC/FexEPsM4ez8AAACAAAAAgAAAAIAAAIC/am7BPhEHbb8AAACAAAAAgAAAAIAAAIC/AAAAAAAAgD8AAACAAAAAgAAAAIAAAIC/lL8MPw7WVb8AAACAFexEvsM4ez8AAAAAAAAAgAAAAAAAAIC/AAAAgAAAAAAAAIC/UKgzP/xeNr8AAACAam7BvhEHbT8AAAAAAAAAgAAAAIAAAIC/am7BvhEHbT8AAAAAAAAAAAAAAAAAAIA/lL8Mvw7WVT8AAACAAAAAgAAAAIAAAIC/AAAAAAAAAIAAAIA/UKgzP/xeNr8AAACAAAAAgAAAAIAAAIC/J95TP7yxD78AAACAFexEvsM4ez8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAIAAAIA/lL8MPw7WVb8AAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAAAAAAAAAAAAAIA/am7BPhEHbb8AAACAAAAAAAAAAIAAAIA/FexEPsM4ez8AAACAAAAAAAAAAAAAAIA/FexEPsM4e78AAACAAAAAAAAAAIAAAIA/am7BPhEHbT8AAACAAAAAgAAAgL8AAACAAAAAAAAAAIAAAIA/AAAAAAAAAAAAAIA/lL8MPw7WVT8AAACAFexEvsM4e78AAAAAAAAAAAAAAIAAAIA/AAAAAAAAAAAAAIA/UKgzP/xeNj8AAACAam7BvhEHbb8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAIAAAIA/J95TP7yxDz8AAACAlL8Mvw7WVb8AAAAAAAAAAAAAAIAAAIA/AAAAAAAAAIAAAIA/ofxrP850xj4AAACAyu96v26nSj4AAACAAAAAAAAAAAAAAIA/AACAvwAAAAAAAAAAAAAAgAAAAIAAAIC/UKgzv/xeNr8AAAAAAAAAAAAAAIAAAIA/AAAAAAAAAIAAAIA/yu96P26nSj4AAACAofxrv850xj4AAACAAAAAgAAAAIAAAIA/J95Tv7yxD78AAAAAAAAAAAAAAIAAAIA/AAAAAAAAAIAAAIA/AACAPwAAAIAAAACAJ95Tv7yxDz8AAAAAAAAAAAAAAAAAAIA/ofxrv850xr4AAAAAAAAAAAAAAIAAAIA/AAAAAAAAAIAAAIA/yu96P26nSr4AAACAUKgzv/xeNj8AAAAAAAAAgAAAAIAAAIA/yu96v26nSr4AAACAAAAAAAAAAIAAAIA/AAAAAAAAAAAAAIA/ofxrP850xr4AAACAavuHPv2Fpb4dhGi/IlQ9P//EKj/W5rc9w7YNPgNuPb4SE3m/JJFKP0SyGj8WR789m6oCPQxpM723n3+/dBlXP+PcCD/hWbk9kDBmvfL+7j3w132/ubRgPyU+8T4BwrE9KpnMvQuxgT6xU3a/HLVqP3Qsxz5DU7g9r+SuvbqokT44cnS/UwN1PzrZjD4qxro9gC47vSo+ZD4QSXm/Tgx7P2FLMz4qMbM9+UxqvL9r7z3hN36/7ut9P0eIwT0RSK49BYA3uwAAAIC+/3+/RhJ/P4IRA7quR649/JJtvEmf773vNn6/m+R9P4lfw73R5K49YT49vYRCZL5CR3m/1P56P9IcNL7jn7Q9LeqvvRabkb5ScXS/jfF0P/Uojb7m07w9xmzNvemKgb72VXa/p55qP55rx74OL7s9dppmvSyX7r0Y2X2/DZZgP+2B8b7Kp7U993sDPWrRMz0Dn3+/HfFWP48DCb902r09xQgOPhQ+PT5uEnm/zltKP3HfGr92MMQ9/D+IPj9VpT6/gmi/hw49P6z7Kr/5B709bUfHPjKA3T4uMFC/ENouP/TBOb//Aqs9Frb5Pk7Q+T4zUzm/UVohP0n8Rb+0Qos9rooOPwpG9j5EXS2/fksYPwpQTb+29Fs9g08OP0tnVL/hqk8992obPxUi3T6UwCq/uFUAP5T7XL8hIHQ9urEtP7aIwT61QCG/AAAAgAAAAIAAAIC/YTnFPlCZa7/CrIs9CtU3P9ihtD6+khm/F7fROAAAAAAAAIC/ueeKPl3Cdb8M7Y09F7fROAAAAAAAAIC/UqEJPpcdfb+594Y9AAAAABN6f7+L3II9AAAAgAAAAIAAAIC/UqEJvpcdfb+594Y9F7fRuAAAAAAAAIC/ueeKvl3Cdb8M7Y09F7fRuAAAAAAAAIC/CtU3v9ihtD6+khm/YTnFvlCZa7/CrIs9AAAAAAAAAIAAAIC/urEtv7aIwT61QCG/uFUAv5T7XL8hIHQ992obvxUi3T6UwCq/g08Ov0tnVL/hqk89fksYvwpQTb+29Fs9rooOvwpG9j5EXS2/UVohv0n8Rb+0Qos9Frb5vk7Q+T4zUzm/ENouv/TBOb//Aqs9bUfHvjKA3T4uMFC/hw49v6z7Kr/5B709/D+Ivj9VpT6/gmi/WFlKv5PiGr9tNMQ9xQgOvhQ+PT5uEnm/HfFWv48DCb902r0993sDvWrRMz0Dn3+/DZZgv+2B8b7Kp7U9dppmPSyX7r0Y2X2/p55qv55rx74OL7s9xmzNPemKgb72VXa/jfF0v/Uojb7m07w9LeqvPRabkb5ScXS/1P56v9IcNL7jn7Q9YT49PYRCZL5CR3m/m+R9v4lfw73R5K49/JJtPEmf773vNn6/RhJ/v4IRA7quR649BYA3OwAAAIC+/3+/7ut9v0eIwT0RSK49+UxqPL9r7z3hN36/Tgx7v2FLMz4qMbM9gC47PSo+ZD4QSXm/UwN1vzrZjD4qxro9r+SuPbqokT44cnS/HLVqv3Qsxz5DU7g9KpnMPQuxgT6xU3a/brdgv/Iz8T4lxLE9kDBmPfL+7j3w132/dBlXv+PcCD/hWbk9m6oCvQxpM723n3+/JJFKv0SyGj8WR789w7YNvgNuPb4SE3m/IlQ9v//EKj/W5rc9ivyHvj96pb4Jhmi/JDEvv2mCOT8I5qU9pPnGvrLC3b4VMVC//b4hvxm3RT/XjoY9TGT5vuYo+r7dUDm/ua4Yv78PTT8e81I9QGMOv5mh9r4iXS2/O0obv+F93b6dwCq/qqoOv/kxVD/jeEc9r5Ytv2/Wwb5+RiG/s7EAvxfOXD8TwWw9Y8A3v2fitL54mBm/xYbFvkORaz+YMIg9AAAAAAAAAAAAAIC/HQ2LvoHFdT9qO4o9F7fRuAAAAIAAAIC/ycwMvsAHfT+PGIQ9F7fRuAAAAIAAAIC/AAAAgAAAAAAAAIC/AAAAgNB9fz+XBoE9F7fROAAAAIAAAIC/ycwMPsAHfT+PGIQ9F7fROAAAAIAAAIC/HQ2LPoHFdT9qO4o9AAAAgAAAAAAAAIC/xYbFPkORaz+YMIg9Y8A3P2fitL54mBm/s7EAPxfOXD8TwWw9r5YtP2/Wwb5+RiG/qqoOP/kxVD/jeEc9O0obP+F93b6dwCq/QGMOP5mh9r4iXS2/ua4YP78PTT8e81I9TGT5PuYo+r7dUDm//b4hPxm3RT/XjoY9pPnGPrLC3b4VMVC/JDEvP2mCOT8I5qU9MthBP4zPJj/QjDk9HRJMP0QaGj9crj89EcJWP6zaCj9rjDk9UwRhPyEk8z6dKzI99SFrP3MpyT5k6Dc9e7l0P/hvlD6Omzs96Rt7PwQMQj4XOTQ9lYR+P1jvyT2s5i49f8R/P9R/N7r7fC490nt+PyeXzL0DTi89Igp7P0RiQ77i3TU9gKB0PwYKlb7Aoz093QBrP1q5yb4gxjo9dN1gP62n876FRDY91JZWP10XC78wED49sN9LP8NWGr+CmkQ9sJtBP8UPJ7943j49fuo2P8nEMr8r5y49+ocrP43PPb8wdxM9L1wfP7w3SL/deOk8gXURP0qPUr+XE9A8B4n/Pty3Xb991Oc8GN3MPoR1ar+0Zwg9a82MPhL4db82Ig49LH4QPjhMfb+OLAc9AAAAAHHef78IEgM9LH4QvjhMfb+OLAc9a82MvhL4db82Ig49G+jMvh1zar9OZgg9B4n/vty3Xb991Oc8gXURv0qPUr+XE9A8L1wfv7w3SL/deOk8+ocrv43PPb8wdxM9fuo2v8nEMr8r5y49sJtBv8UPJ7943j49sN9Lv8NWGr+CmkQ91JZWv10XC78wED49dN1gv62n876FRDY93QBrv1q5yb4gxjo9gKB0vwYKlb7Aoz09Igp7v0RiQ77i3TU90nt+vyeXzL0DTi89f8R/v9R/N7r7fC49lYR+v1jvyT2s5i496Rt7vwQMQj4XOTQ9e7l0v/hvlD6Omzs99SFrv3MpyT5k6Dc9UwRhvyEk8z6dKzI9EcJWv6zaCj9rjDk9HRJMv0QaGj9crj89MthBv4zPJj/QjDk9yjA3v4GBMj8w+yk9r9Urv/qMPT8KjA49R6ofvxD8Rz86deA8PsQRv/5aUj/aEMc8hgcAvxSTXT+pd+A8HEXNvuJgaj9htwQ94PKMvtD0dT+kcAo9ETsSvsc9fT/STQQ9AAAAgEbffz8GbwE9ETsSPsc9fT/STQQ94PKMPtD0dT+kcAo9HEXNPuJgaj9htwQ9hgcAPxSTXT+pd+A8PsQRP/5aUj/aEMc8R6ofPxD8Rz86deA8r9UrP/qMPT8KjA49yjA3P4GBMj8w+yk9VEf6Pqyf0T4CNUU/ez1EPzFlJD8AAACApkACP1OBxD7vRUU/wFlMP4gyGj8AAACAQjIIPxVpsz6/VEU/EcRVP+baDD8AAACA3lUPP/0Vmz65bUU/pyJhP8K48z4AAACAwysWPwHoez4IiEU/nQ1sP+ojxj4AAACA+Z8bP5B3Pj4MnEU/8sd0P+volT4AAACApYMfP9bL/z2NqEU/gP56PxeDST4AAACAnNghP5lvgT3Qr0U/wrp+P5vIyz0AAACA56EiPz5IHboYtEU/+v9/P/Tta7oAAACAxdEhPxmwg713r0U/6q5+Pw10z70AAACAe3UfP6IfAb48p0U/5Od6P6JDS74AAACAZ4sbP8+WP77lmkU/2aV0P+rGlr4AAACAFxEWP2DtfL5th0U/POFrP+L2xr4AAACAWTUPPzqMm74RbkU/ie1gP6B89L4AAACADAsIPzPfs77pVEU//IxVP1kuDb8AAACAHB4CP4PnxL5BQ0U/eh5MP/eAGr8AAACAEQP6PiT50b7cMkU/6P5DP8SvJL8AAACAs+3vPjeZ3b5kJkU/NwU8P4i8Lb8AAACA6r7jPs5Z6r5sE0U/+1wyPxajN78AAACAjOrRPsu4+r4K/UQ/QEgkP7VVRL8AAACAgVG6PueABr8p5EQ/IqsRP+qDUr8AAACATmSdPmeeD7/vw0Q/H+r1PteJYL8AAACACZx7PklUF79Mq0Q/BHfEPixnbL8AAACAohc3PnF3Hb9mlUQ/0piOPvfedb8AAACAAinCPdBCIr/4g0Q/i1kXPjYwfb8AAACAAAAAgAAAgL8AAAAAAAAAAOUZJL91fEQ/i1kXvjYwfb8AAAAAAinCvdBCIr/4g0Q/0piOvvfedb8AAAAAohc3vnF3Hb9mlUQ/BHfEvixnbL8AAAAACZx7vklUF79Mq0Q/H+r1vteJYL8AAACATmSdvmeeD7/vw0Q/IqsRv+qDUr8AAACAgVG6vueABr8p5EQ/QEgkv7VVRL8AAACAjOrRvsu4+r4K/UQ/+1wyvxajN78AAAAA6r7jvs5Z6r5sE0U/NwU8v4i8Lb8AAAAAs+3vvjeZ3b5kJkU/6P5Dv8SvJL8AAAAAEQP6viT50b7cMkU/3iBMv9B9Gr8AAAAAHB4Cv4PnxL5BQ0U//IxVv1kuDb8AAAAADAsIvzPfs77pVEU/ie1gv6B89L4AAAAAWTUPvzqMm74RbkU/POFrv+L2xr4AAAAAFxEWv2DtfL5th0U/2aV0v+rGlr4AAAAAZ4sbv8+WP77lmkU/5Od6v6JDS74AAAAAe3Ufv6IfAb48p0U/6q5+vw10z70AAACAxdEhvxmwg713r0U/+v9/v/Tta7oAAAAA56Eivz5IHboYtEU/wrp+v5vIyz0AAAAAnNghv5lvgT3Qr0U/gP56vxeDST4AAAAApYMfv9bL/z2NqEU/8sd0v+volT4AAAAA+Z8bv5B3Pj4MnEU/nQ1sv+ojxj4AAAAAwysWvwHoez4IiEU/pyJhv8K48z4AAAAA3lUPv/0Vmz65bUU/EcRVv+baDD8AAAAAki8Iv4tlsz5pV0U/wFlMv4gyGj8AAAAApkACv1OBxD7vRUU/ez1EvzFlJD8AAAAAZUL6voqb0T6tN0U/AEE8v717LT8AAAAAADvwvlZJ3T5KJUU/JJwyv6hlNz8AAACAgAnkvv4G6j53FkU/foEkv8ElRD8AAACAGznSvil3+j72/EQ/ZuURv41bUj8AAACAvp+6vmZmBj+940Q/xUb2vnNwYD8AAAAAbaadvkWLDz+pxEQ/h87EvvpUbD8AAAAAXQJ8vjdMFz9SqUQ/x9iOvq/VdT8AAAAAwWM3vkZ1HT+ykkQ/1IwXvksufT8AAAAA7ZDCvQZCIj8Eg0Q/AAAAAOUZJD91fEQ/AAAAgAAAgD8AAAAA7ZDCPQZCIj8Eg0Q/1IwXPksufT8AAACAwWM3PkZ1HT+ykkQ/x9iOPq/VdT8AAACAXQJ8PjdMFz9SqUQ/h87EPvpUbD8AAACAbaadPkWLDz+pxEQ/xUb2PnNwYD8AAACAvp+6PmZmBj+940Q/ZuURP41bUj8AAACAGznSPil3+j72/EQ/foEkP8ElRD8AAACAgAnkPv4G6j53FkU/JJwyP6hlNz8AAACAADvwPlZJ3T5KJUU/AEE8P717LT8AAACAQy36vnd7Wr9LqTm+AAAAgAAAAIAAAIC/wbi8PjZjnT5GlmA/uzr6PjWt0T5pNUU/3G0Ev/grVb+TPUq+AAAAgAAAAIAAAIC/mpvGPtMKlz7oil8/OzkCPz2axD6hREU/eo4av/p2Rb/HJE6+AAAAgAAAAIAAAIC/Sq26PrMhXz5Jwmc/ViwIPwZ3sz6qVUU/ntQmvwaFOL+u3HG+AAAAgAAAAIAAAIC/JNG3PnSIST5oj2k/iEkPPyY+mz7IbkU/N3RFv7RYGL9AHme+AAAAgAAAAIAAAIC/L1G4Pof6Cz47Qmw/oCQWP6s1fD5Eh0U/Xihbv86U8r7Ec1O+AAAAgAAAAIAAAIC/fzS1Pny/4z2Cu20/wJ0bP3vDPj45mUU/6O5mv3H2xL5lSki+AAAAgAAAAIAAAIC/2THCPoHGmD22GWw/nn4fP5IbAD5vqkU/2Y5xv6XDkb7kJy2+AAAAgAAAAIAAAIC/r865PltyCj34Y24/nNghP5lvgT3Qr0U/etFzv+Qncb6rJUa+AAAAgAAAAIAAAIC/ABTBPo0eJzzPFW0/56EiPz5IHboYtEU/aK90v9x2Pr5IKmm+AAAAgAAAAIAAAIC/QUnGPvtVKL25yWs/gdEhP0/kg70kr0U/yKl4v4SLsL1T02K+AAAAgAAAAIAAAIC/b4LNPkQzgL2r7Gk/cHAfP0pVAb4bqUU/N8d6v8weBT1HD0u+AAAAgAAAAIAAAIC/EkzfPhzjC75cs2M/CIUbP63lP74gm0U/gRx5v3zDAj7DZkS+AAAAgAAAAIAAAIC/mQPnPufCJL5pt2A/8AkWPwM7fb6lhkU/kWN1vzIwRD5Q81e+AAAAgAAAAIAAAIC/+2oGP5Jyk77GBE0//ygPP2C0m74cb0U/OXVxvyhPXj5vxIC+AAAAgAAAAIAAAIC/DAsIPzPfs77pVEU/L+gJP3dBoL4sPkg/+6Vtv2J5ej62XI++AAAAgAAAAIAAAIC/GxMCP833xL5yRkU/wsApPxtk+76zoxA/EFtpvxtgkD6EO5m+AAAAgAAAAIAAAIC/euz5PksJ0r64NUU/3XIbP1r+Br9qJRg/oeViv6LdtT42Hpi+AAAAgAAAAIAAAIC/69PvPtWz3b6/JkU/21ErP8rEEr9iB/I+CS5Tv2h2AT+ISIG+AAAAgAAAAIAAAIC/XJfjPuOA6r44E0U/vSsnP69ZN7/0HHy+/7IsP2icE7+l++s+rZVEv2yhFz+pwXm+AAAAgAAAAIAAAIC/kMTRPpzU+r5M/kQ/Ld8ePzHsPr+NAni+/5Ysv4P8ND9u0lq+AAAAgAAAAIAAAIC/nQ66PiOaBr+74kQ/tgX/PnnZK78FhAy/EfcRv1CcTT9g1jC+AAAAgAAAAIAAAIC/TjCdPuerD794xEQ/VgHLPk+sGr/d8TC/cwr5vg26XD/CyxC+AAAAgAAAAIAAAIC/P7l0PsDY975qfVe/mH97PoBZF7+PqUQ/9Cm8vgREbT9w5529AAAAgAAAAIAAAIC/n5bdPdclsb4clm6/90M2PmqJHb9Lk0Q/S32Svr7SdD/JIXS9AAAAgAAAAIAAAIC/r1aOPf01nr4I0nK/8b3BPYRHIr+8gUQ/MXlUvtDseT+y8X29AAAAAOUZJL91fEQ/AAAAgAAAAIAAAIC/IQJnPHTZeb6VPHi/Ik8NvvOJfD8dCrW98b3BvYRHIr+8gUQ/QRDHvPmUQ77LNXu/AAAAgAAAAIAAAIC/90M2vmqJHb9Lk0Q/Lp3evQ+/ez8f4xS+M+IlvQHlLr56Bny/AAAAgAAAAIAAAIC/mH97voBZF7+PqUQ/RsZcvdWzGb4suXy//bjRubhYfT82DRO+AAAAgAAAAIAAAIC/TjCdvuerD794xEQ/yy+IvYBTAb4BYX2/AAAAgAAAAIAAAIC/WpqiPbLqez8zAyO+nQ66viOaBr+74kQ/gxeVvYO4671nnX2/AAAAgAAAAIAAAIC/fyYPPoHmeD9Y/j++kMTRvpzU+r5M/kQ/7kOlvXr4y71c432/AAAAgAAAAIAAAIC//VdsPhsGdD9840e+XJfjvuOA6r44E0U/CJeqvffQvL0nBH6/AAAAgAAAAIAAAIC/HImOPo+obz9C2Fu+69PvvtWz3b6/JkU/AmOyvQYTpb3eMH6/AAAAgAAAAIAAAIC/YarPPteuZD/jWEa+euz5vksJ0r64NUU/RGu8vaysnL0uKX6/AAAAgAAAAIAAAIC/5Vj5PnmgWj/6ZDu+GxMCv833xL5yRkU/CZ68vXP1l70LNH6/AAAAgAAAAIAAAIC/y+IDP51kVT9pLUy+DAsIvzPfs77pVEU/06K9vT8Bib0BU36/AAAAgAAAAIAAAIC/tBUaP+y0RT8aE1C+/ygPv2C0m74cb0U/oN3Gve31W71Ka36/AAAAgAAAAIAAAIC/pl8mP6vHOD/8tXO+8AkWvwM7fb6lhkU/OifLvUR+N72men6/AAAAgAAAAIAAAIC/bxJFP8GnGD/yEGm+CIUbv63lP74gm0U/JuzRvYvkA72nhH6/AAAAgAAAAIAAAIC/mtpaPytA8z6vZlW+cHAfv0pVAb4bqUU/F6jXvYNPr7yOhH6/AAAAgAAAAIAAAIC/0bRmP36UxT7QCEq+gdEhv0/kg70kr0U/pObZvawcJ7yTiH6/AAAAgAAAAIAAAIC/qWZxP2Zgkj5Cli6+56Eivz5IHboYtEU/dsHbvcQuEDt3hX6/AAAAgAAAAIAAAIC/XLhzP7P6cT5/Eke+nNghv5lvgT3Qr0U/Ps/dvV8QPjwPen6/AAAAgAAAAIAAAIC/ZKB0P94sPz5RkWm+nn4fv5IbAD5vqkU/DGjevU3LzDzQZ36/AAAAgAAAAIAAAIC/hKR4P8T2sT286GK+wJ0bv3vDPj45mUU/vdDeveHlDD33U36/AAAAgAAAAIAAAIC/8Ml6PzZCAr1E90q+oCQWv6s1fD5Eh0U/5JbdvRr6Sz14LX6/AAAAgAAAAIAAAIC/NCZ5P6ENAr6YGkS+iEkPvyY+mz7IbkU/Z13cvQCIdD3wDX6/AAAAgAAAAIAAAIC/x3N1P2SVQ77CWFe+pSkIv3tzsz5TWEU/g0PYvcvrnj3dyn2/AAAAgAAAAIAAAIC/YYlxP/gAXr67ToC+OzkCvz2axD6hREU/j4TavSG3rz3Vln2/AAAAgAAAAIAAAIC/fL9tP2xeer7/vo6+uzr6vjWt0T5pNUU/BCHbvSNEtj04gn2/AAAAgAAAAIAAAIC/rHVpP4NxkL6RiJi+5iPwvk9Z3T7YJ0U/fRfRve3vwT1+gX2/AAAAgAAAAIAAAIC/h/5iPwIRtr6eS5e+debjvrQy6j6cE0U/vTbNvVPK5T05Fn2/AAAAgAAAAIAAAIC/3kxTP1SCAb9QToC+PgjSvqGV+j5PAEU/GfHJvR91+T091ny/AAAAgAAAAIAAAIC/DLpEP7SlF7/ey3e+31y6vqZ/Bj9U4kQ/fM67vVeOFz4DF3y/AAAAgAAAAIAAAIC/Or8sP3j9NL9Ox1i+b3KdvseYDz82xUQ/V7ywvTQIKD7Jj3u/AAAAgAAAAIAAAIC/fiYSP/GXTb/AsS6+vel7vitNFz+PqkQ/auqVvW8/Vz7vk3m/AAAAgAAAAIAAAIC/xHL5PgSzXL/wpA6++5I2vjCDHT+0k0Q/DSptvS5efj5TiHe/AAAAgAAAAIAAAIC/IHq8PmM/bb+om5m93CXCvbtGIj/IgEQ/kg8cvQ63kz6W63S/AAAAgAAAAIAAAIC/69WSPobNdL+E62u9AAAAgAAAAIAAAIC/AAAAAOUZJD91fEQ/DA35PARf4D5W+mW/mvxUPjbteb+1kna9AAAAgAAAAIAAAIC/3CXCPbtGIj/IgEQ/frcNPp2PfL+mwrG9zJchPhYzJz+wmT2/AAAAgAAAAIAAAIC/uHDfPavHe7/CqRO++5I2PjCDHT+0k0Q/FOJhPvomOz97SiW/AAAAAPRnfb85ZxG+AAAAgAAAAIAAAIC/vel7PitNFz+PqkQ/MfiPPvSkST+eVQy/8bTkPmGcYD+xTDM+Bwqkvd/4e79DRiG+AAAAgAAAAIAAAIC/b3KdPseYDz82xUQ/6GzwPgHfWj/6k2E+cggKvkv7eL9/C0K+AAAAgAAAAIAAAIC/31y6PqZ/Bj9U4kQ/FOnVPq9LBj/l5T0/DFwBP56ETz8IgZc+5pxvvuPpc780JEa+AAAAgAAAAIAAAIC/PgjSPqGV+j5PAEU/HLvaPrgSBD97FT4/3C6QvquLb7/fgFm+AAAAgAAAAIAAAIC/k+LcPoeV2D4K/Us/debjPrQy6j6cE0U/bOzPvmavZL8DOUW+AAAAgAAAAIAAAIC/HWm+PuGOoj5lTl8/5iPwPk9Z3T7YJ0U/WUphv9DP276x4U++Y+mIPkpnpr7zOGi/GcVsvyZ+qr65ADy+HBoNPly3PL5KIXm/dvhzv0Bdfr4+kDG+x0/zPPHkJb1KrX+/Xjh0v75LVb6U31y+uxhivUp+6j1r7H2/uCl3v52cAL4LrGm+g5HLvdJhfz72mXa/mXt6vxX71LusV1O+bSOwvbntkT5aZHS/Zfx5vzLvyT0tM0S+kS87vUAlZD58Snm/xuZ2v1lnLz4fBU6+F+xrvOqh8D03M36/2P5yv72tWD5pfW6+BYA3uwAAAAC+/3+/H0Jvv10IbD6Cs4q+wTJvvL2h8L0HM36/+FdrvyyHhz6gGJW+MNM8vUQLZL69Snm/4ERmv6+IoT6Oxpq+lySxvYHckb4FZHS/j6Rbv+A63T7xOo6+v2PMvQsuf76Ymna/QD1Iv4x6Ez+M/XK+zelivaB96r2y632/H/01v9UiKj/Knmu+CFDzPEB8JT2OrX+/dlIYv9hsSD86EDq+4E4NPmKDPD7hIXm/h5wBv7JxWT8Mkxi+cBuJPvsvpj55O2i/Qc/KvnfWaT95fr+9Cg/JPoDR3j5OaE+/h2uYvknwcz8uYm69Hb77PnF2+j6taji/1VJjvtYbeT+WiX294NIOPyXD9T5JUC2/Ym4Wvq1SfD/Qmqq9kz0bP6GL3T6qxyq/5+XhvQbvez/ScA6+C3csP7IEwz5tHyK/yC/mvF8FfT8SFRm+AAAAgAAAAIAAAIC/CtU3P9ihtD6+khm/F7fROAAAAAAAAIC/It6CPWS5fD9jmxW+F7fROAAAAAAAAIC/kqLwPbEHej9OAji+AAAAgAAAAIAAAIC/xMhLPsTYdT/L/ke+F7fRuAAAAAAAAIC/A5KLPl6WcD+PC1O+F7fRuAAAAAAAAIC/CwO4PgT8aD8KQFO+CtU3v9ihtD6+khm/AAAAAAAAAIAAAIC/0CHzPs67XD+ZajS+C3csv7IEwz5tHyK/weX/PuVRWD/Ew0K+kz0bv6GL3T6qxyq/rvwKPzBxUD+ailK+4NIOvyXD9T5JUC2/q2wlPy/tOz+OtFW+Hb77vnF2+j6taji/vJAuP8DELz8qIIG+Cg/JvoDR3j5OaE+/jrFUP90MBD8k7FW+cBuJvvsvpj55O2i/IwZhP5h33D4Vt1G+4E4NvmKDPD7hIXm/cpdsP30Oqz4dij2+CFDzvEB8JT2OrX+/ZNhzP1h+fz4esTK+zeliPaB96r2y632/DSR0P+EcVj5EfF2+v2PMPQsuf76Ymna/WyB3PxNWAT4E5Gm+lySxPYHckb4FZHS/P3t6P0cx7ztgV1O+MNM8PUQLZL69Snm/jAN6P6yAyL04/0O+wTJvPL2h8L0HM36/m/V2PxSxLr5+g02+BYA3OwAAAAC+/3+/oBFzPxhEWL7Vqm2+F+xrPOqh8D03M36/eVpvPxnSa75BIoq+kS87PUAlZD58Snm/yHJrP4SHh76bbpS+bSOwPbntkT5aZHS/9F5mP+qvob7cAZq+g5HLPdJhfz72mXa/NcBbP6Nj3b7wT42+uxhiPUp+6j1r7H2/CF5IPxyBE7+AC3G+x0/zvPHkJb1KrX+/Pyw2P3IdKr8clGm+HBoNvly3PL5KIXm/4X4YP+5qSL/15ze+Y+mIvkpnpr7zOGi/HtEBP2prWb+GUha+O8PIvkkj376tZE+/bCvLPmTQab/QMbu9jW/7vinF+r67aji/YruYPqrrc7/iMma9fasOv8oe9r42UC2/Fe9jPrYaeb84wHW9hh4bv7vc3b6OySq/lNYWPh5YfL/AHqe91FssvzNSw74JJSK/ErTiPTD4e7/RGQ2+Y8A3v2fitL54mBm/AAAAAAAAAAAAAIC/vF/lPFAUfb/3jBe+SU2EvcnGfL/p3RO+F7fRuAAAAIAAAIC/kiHsvTsVer9FUTi+F7fRuAAAAIAAAIC/TPFJvl/mdb/s0Ei+AAAAgAAAAAAAAIC/HWOOvrpbcL/Jqk++F7fROAAAAIAAAIC/e0K4vuv/aL9KHVK+F7fROAAAAIAAAIC/y4HzvoqyXL/yGDO+AAAAgAAAAAAAAIC/Y8A3P2fitL54mBm/BIMAv9gWWL/Z60C+1FssPzNSw74JJSK/Un0Lvx45UL8Ur1C+hh4bP7vc3b6OySq/MuQlv96mO798xFO+fasOP8oe9r42UC2/RAAvv1aDL783J4C+jW/7PinF+r67aji/AQdVv9K3A78U4FO+O8PIPkkj376tZE+/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwUAAwABAAEAPwA9AD0AOwA5ADkANwA1ADUAMwAxADEALgAsACwAKgAoACgAJgAkACQAIgAgACAAHgAcABwAGgAYABgAFgAUABQAEgAQABAADwANAA0ACwAJAAkABwAFAAUAAQA9AD0AOQA1ADUAMQAsACwAKAAkACQAIAAcABwAGAAUABQAEAANAA0ACQAFAAUAPQA1ADUALAAkACQAHAAUABQADQAFAAUANQAkACQAFAAFAFEAUwCTAFEAkwCRABsAHQBcABsAXABaAAAAAgBBAAAAQQBDADYAOAB5ADYAeQB3AB0AHwBeAB0AXgBcAAIABABFAAIARQBBADgAOgB7ADgAewB5AB8AIQBgAB8AYABeAAQABgBHAAQARwBFADoAPAB9ADoAfQB7ACEAIwBiACEAYgBgAAYACABJAAYASQBHADwAPgB/ADwAfwB9ACMAJQBkACMAZABiAAgACgBLAAgASwBJAD4AAABDAD4AQwB/ACUAJwBmACUAZgBkAAoADABNAAoATQBLACcAKQBoACcAaABmAAwADgBPAAwATwBNACkAKwBqACkAagBoAA4AEQBQAA4AUABPACsALQBsACsAbABqABEAEwBSABEAUgBQAC0ALwBuAC0AbgBsABMAFQBUABMAVABSAC8AMABxAC8AcQBuABUAFwBWABUAVgBUADAAMgBzADAAcwBxABcAGQBYABcAWABWADIANAB1ADIAdQBzABkAGwBaABkAWgBYADQANgB3ADQAdwB1AJYAmADYAJYA2ADWAG0AbwCvAG0ArwCtAFMAVQCVAFMAlQCTAG8AcACwAG8AsACvAFUAVwCXAFUAlwCVAHAAcgCyAHAAsgCwAFcAWQCZAFcAmQCXAHIAdAC0AHIAtACyAFkAWwCbAFkAmwCZAHQAdgC2AHQAtgC0AFsAXQCdAFsAnQCbAEIAQACAAEIAgACCAHYAeAC4AHYAuAC2AF0AXwCfAF0AnwCdAEAARACEAEAAhACAAHgAegC6AHgAugC4AF8AYQChAF8AoQCfAEQARgCGAEQAhgCEAHoAfAC8AHoAvAC6AGEAYwCjAGEAowChAEYASACIAEYAiACGAHwAfgC+AHwAvgC8AGMAZQClAGMApQCjAEgASgCKAEgAigCIAH4AQgCCAH4AggC+AGUAZwCnAGUApwClAEoATACMAEoAjACKAGcAaQCpAGcAqQCnAEwATgCOAEwAjgCMAGkAawCrAGkAqwCpAE4AUQCRAE4AkQCOAGsAbQCtAGsArQCrAN0A3wAfAd0AHwEdAbMAtQD1ALMA9QDzAJgAmgDaAJgA2gDYALUAtwD3ALUA9wD1AJoAnADcAJoA3ADaAIMAgQDBAIMAwQDDALcAuQD5ALcA+QD3AJwAngDeAJwA3gDcAIEAhQDFAIEAxQDBALkAuwD7ALkA+wD5AJ4AoADgAJ4A4ADeAIUAhwDHAIUAxwDFALsAvQD9ALsA/QD7AKAAogDiAKAA4gDgAIcAiQDJAIcAyQDHAL0AvwD/AL0A/wD9AKIApADkAKIA5ADiAIkAiwDLAIkAywDJAL8AgwDDAL8AwwD/AKQApgDmAKQA5gDkAIsAjQDNAIsAzQDLAKYAqADoAKYA6ADmAI0AjwDPAI0AzwDNAKgAqgDqAKgA6gDoAI8AkADQAI8A0ADPAKoArADsAKoA7ADqAJAAkgDSAJAA0gDQAKwArgDuAKwA7gDsAJIAlADUAJIA1ADSAK4AsQDxAK4A8QDuAJQAlgDWAJQA1gDUALEAswDzALEA8wDxACIBJAFkASIBZAFiAcAAxAAEAcAABAEAAfgA+gA6AfgAOgE4Ad8A4QAhAd8AIQEfAcQAxgAGAcQABgEEAfoA/AA8AfoAPAE6AeEA4wAjAeEAIwEhAcYAyAAIAcYACAEGAfwA/gA+AfwAPgE8AeMA5QAlAeMAJQEjAcgAygAKAcgACgEIAf4AwgACAf4AAgE+AeUA5wAnAeUAJwElAcoAzAAMAcoADAEKAecA6QApAecAKQEnAcwAzgAOAcwADgEMAekA6wArAekAKwEpAc4A0QARAc4AEQEOAesA7QAtAesALQErAdEA0wATAdEAEwERAe0A7wAvAe0ALwEtAdMA1QAVAdMAFQETAe8A8AAwAe8AMAEvAdUA1wAXAdUAFwEVAfAA8gAyAfAAMgEwAdcA2QAZAdcAGQEXAfIA9AA0AfIANAEyAdkA2wAbAdkAGwEZAfQA9gA2AfQANgE0AdsA3QAdAdsAHQEbAcIAwAAAAcIAAAECAfYA+AA4AfYAOAE2AVEBUwGJAVEBiQGIAQkBCwFLAQkBSwFJAT8BAwFDAT8BQwF/ASQBJgFmASQBZgFkAQsBDQFNAQsBTQFLASYBKAFoASYBaAFmAQ0BDwFPAQ0BTwFNASgBKgFqASgBagFoAQ8BEAFQAQ8BUAFPASoBLAFsASoBbAFqARABEgFSARABUgFQASwBLgFuASwBbgFsARIBFAFUARIBVAFSAS4BMQFxAS4BcQFuARQBFgFWARQBVgFUATEBMwFzATEBcwFxARYBGAFYARYBWAFWATMBNQF1ATMBdQFzARgBGgFaARgBWgFYATUBNwF3ATUBdwF1ARoBHAFcARoBXAFaAQMBAQFBAQMBQQFDATcBOQF5ATcBeQF3ARwBHgFeARwBXgFcAQEBBQFFAQEBRQFBATkBOwF7ATkBewF5AR4BIAFgAR4BYAFeAQUBBwFHAQUBRwFFATsBPQF9ATsBfQF7ASABIgFiASABYgFgAQcBCQFJAQcBSQFHAT0BPwF/AT0BfwF9AYsBjAGsAYsBrAGrAW0BbwGXAW0BlwGWAVMBVQGKAVMBigGJAW8BcAGYAW8BmAGXAVUBVwGLAVUBiwGKAXABcgGZAXABmQGYAVcBWQGMAVcBjAGLAXIBdAGaAXIBmgGZAVkBWwGNAVkBjQGMAXQBdgGbAXQBmwGaAVsBXQGOAVsBjgGNAUIBQAGAAUIBgAGBAXYBeAGcAXYBnAGbAV0BXwGPAV0BjwGOAUABRAGCAUABggGAAXgBegGdAXgBnQGcAV8BYQGQAV8BkAGPAUQBRgGDAUQBgwGCAXoBfAGeAXoBngGdAWEBYwGRAWEBkQGQAUYBSAGEAUYBhAGDAXwBfgGfAXwBnwGeAWMBZQGSAWMBkgGRAUgBSgGFAUgBhQGEAX4BQgGBAX4BgQGfAWUBZwGTAWUBkwGSAUoBTAGGAUoBhgGFAWcBaQGUAWcBlAGTAUwBTgGHAUwBhwGGAWkBawGVAWkBlQGUAU4BUQGIAU4BiAGHAWsBbQGWAWsBlgGVAZkBmgG6AZkBugG5AYwBjQGtAYwBrQGsAZoBmwG7AZoBuwG6AY0BjgGuAY0BrgGtAYEBgAGgAYEBoAGhAZsBnAG8AZsBvAG7AY4BjwGvAY4BrwGuAYABggGiAYABogGgAZwBnQG9AZwBvQG8AY8BkAGwAY8BsAGvAYIBgwGjAYIBowGiAZ0BngG+AZ0BvgG9AZABkQGxAZABsQGwAYMBhAGkAYMBpAGjAZ4BnwG/AZ4BvwG+AZEBkgGyAZEBsgGxAYQBhQGlAYQBpQGkAZ8BgQGhAZ8BoQG/AZIBkwGzAZIBswGyAYUBhgGmAYUBpgGlAZMBlAG0AZMBtAGzAYYBhwGnAYYBpwGmAZQBlQG1AZQBtQG0AYcBiAGoAYcBqAGnAZUBlgG2AZUBtgG1AYgBiQGpAYgBqQGoAZYBlwG3AZYBtwG2AYkBigGqAYkBqgGpAZcBmAG4AZcBuAG3AYoBiwGrAYoBqwGqAZgBmQG5AZgBuQG4AcUBxwEHAsUBBwIFAqIBowHGAaIBxgHEAaMBpAHIAaMByAHGAYMCgQJMAoMCTAJKAvsB/QE9AvsBPQI7AuAB4gEiAuABIgIgAscByQEJAscBCQIHAv0B/wE/Av0BPwI9AuIB5AEkAuIBJAIiAskBywELAskBCwIJAv8BwwEDAv8BAwI/AuQB5gEmAuQBJgIkAssBzQENAssBDQILAuYB6AEoAuYBKAImAs0BzwEPAs0BDwINAugB6gEqAugBKgIoAs8B0AEQAs8BEAIPAuoB7AEsAuoBLAIqAtAB0gESAtABEgIQAuwB7gEuAuwBLgIsAtIB1AEUAtIBFAISAu4B8QExAu4BMQIuAtQB1gEWAtQBFgIUAvEB8wEzAvEBMwIxAtYB2AEYAtYBGAIWAvMB9QE1AvMBNQIzAtgB2gEaAtgBGgIYAvUB9wE3AvUBNwI1AtoB3AEcAtoBHAIaAsMBwQEBAsMBAQIDAvcB+QE5AvcBOQI3AtwB3gEeAtwBHgIcAsEBxQEFAsEBBQIBAvkB+wE7AvkBOwI5At4B4AEgAt4BIAIeAuQG4QZYAowCigJoAowCaAJmAoECkQJOAoECTgJMAooClgJqAooCagJoApECmgJRApECUQJOApYCngJsApYCbAJqApoCogJTApoCUwJRAp4CpgJuAp4CbgJsAqICqgJVAqICVQJTAqYCrQJwAqYCcAJuAqoCsgJXAqoCVwJVAq0CtQJxAq0CcQJwArICugJZArICWQJXArUCvQJzArUCcwJxAroCwgJbAroCWwJZAr0CxQJ1Ar0CdQJzAsICygJdAsICXQJbAs8CzQJAAs8CQAJCAsUC1QJ3AsUCdwJ1AsoC2gJfAsoCXwJdAs0C3QJEAs0CRAJAAtUC4QJ5AtUCeQJ3AtoC5gJhAtoCYQJfAt0C6QJGAt0CRgJEAuEC7QJ7AuECewJ5AuYC8gJjAuYCYwJhAukC9QJIAukCSAJGAu0C+QJ9Au0CfQJ7AvIC/gJlAvICZQJjAvUCgwJKAvUCSgJIAvkCzwJCAvkCQgJ9Av4CjAJmAv4CZgJlAiUCJwKOAiUCjgL8AqkCoQKhA6kCoQOpAz4CAgLRAj4C0QL3AikDMQOvAykDrwOnAwgCCgKFAggChQLzAp8CpwItBJ8CLQQxBCMCJQL8AiMC/ALwAi8DJwNTBC8DUwRXBDwCPgL3AjwC9wLrAq4CpQKlA64CpQOuAwYCCALzAgYC8wLnAiUDLgOsAyUDrAOjAyECIwLwAiEC8ALkAqMCrAIsBKMCLAQvBDoCPALrAjoC6wLfAiwDIwNRBCwDUQRWBAQCBgLnAgQC5wLbArECqQKpA7ECqQOxAx8CIQLkAh8C5ALYAiEDKQOnAyEDpwOfAzgCOgLfAjgC3wLTAqcCrwIpBKcCKQQtBAACBALbAgAC2wLLAicDHwNPBCcDTwRTBB0CHwLYAh0C2ALIArYCrgKuA7YCrgO2AzYCOALTAjYC0wLDAh0DJQOjAx0DowObAwICAALLAgICywLRAqwCtAIoBKwCKAQsBBsCHQLIAhsCyALAAiMDGwNNBCMDTQRRBDQCNgLDAjQCwwK7ArkCsQKxA7kCsQO5AxkCGwLAAhkCwAK4AhkDIQOfAxkDnwOXAzICNAK7AjICuwKzAq8CtwIlBK8CJQQpBBcCGQK4AhcCuAKwAh8DFwNLBB8DSwRPBDACMgKzAjACswKrAr4CtgK2A74CtgO+AxUCFwKwAhUCsAKoAn0DCwNFBH0DRQT7Ay8CMAKrAi8CqwKkAhUDHQObAxUDmwOTAxMCFQKoAhMCqAKgArQCvAIkBLQCJAQoBC0CLwKkAi0CpAKcAg0DewN9BA0DfQSLAxECEwKgAhECoAKYAhsDEwNJBBsDSQRNBCsCLQKcAisCnAKUAsECuQK5A8ECuQPBAw4CEQKYAg4CmAKPAnoDUANoBHoDaAT4AykCKwKUAikClAKIAhIDGQOXAxIDlwOQAwwCDgKPAgwCjwJ/ArcCvwIhBLcCIQQlBCcCKQKIAicCiAKOAlIDeAN8BFIDfATQAwoCDAJ/AgoCfwKFAhcDEANIBBcDSARLBMYCvgK+A8YCvgPGAwUD/wIBAwUDAQMDA3YDBANCBHYDQgT0Aw4DCAMKAw4DCgMMAwkDFQOTAwkDkwOHA/8CDwMRA/8CEQMBA7wCxAIgBLwCIAQkBAgDFAMWAwgDFgMKAwYDdAN6BAYDegSEAw8DGAMaAw8DGgMRAxMDBwNDBBMDQwRJBBQDHAMeAxQDHgMWA8kCwQLBA8kCwQPJAxgDIAMiAxgDIgMaA3EDfQP7A3ED+wPvAxwDJAMmAxwDJgMeAwIDEgOQAwIDkAOAAyADKAMqAyADKgMiA78CxwIdBL8CHQQhBCQDKwMtAyQDLQMmA3sDbwN3BHsDdwR9BCgDMAMyAygDMgMqAxADAANABBADQARIBCsDMwM1AysDNQMtA84C0AIGBM4CBgTOAzADOAM6AzADOgMyA24DegP4A24D+APsAzMDOwM9AzMDPQM1AwsDCQOHAwsDhwNFBDgDQANCAzgDQgM6A9ICzAIcBNICHATSAzsDQwNFAzsDRQM9A3gDbAN2BHgDdgR8BEADSANKA0ADSgNCAwcDDQOLAwcDiwNDBFEDSwNNA1EDTQNPA9YCxgLGA9YCxgPWA0MDUwNVA0MDVQNFA2oDdgP0A2oD9APoA0gDWANaA0gDWgNKAwQDAgOAAwQDgANCBEsDWwNdA0sDXQNNA8QC1AIaBMQCGgQgBFMDXwNhA1MDYQNVA3QDaAN0BHQDdAR6BFgDZANmA1gDZgNaAwADBgOEAwADhANABFsDZwNpA1sDaQNdA9kCyQLJA9kCyQPZA18DawNtA18DbQNhA2UDcQPvA2UD7wPjA2QDcANyA2QDcgNmA8cC1wIXBMcCFwQdBGcDcwN1A2cDdQNpA28DYwNxBG8DcQR3BGsDdwN5A2sDeQNtA94CzgLOA94CzgPeA3ADfAN+A3ADfgNyA2IDbgPsA2ID7APgA3MDBQMDA3MDAwN1A8wC3AIWBMwCFgQcBHcDUQNPA3cDTwN5A2wDYANwBGwDcAR2BHwDDgMMA3wDDAN+A/wDRgQCBPwDAgT+A/cDZwQFBPcDBQT5A/MDQQQJBPMDCQT1A/AD/AP+A/AD/gPyA+sD9wP5A+sD+QPtA+cD8wP1A+cD9QPpA+QD8APyA+QD8gPmA98D6wPtA98D7QPhA9sD5wPpA9sD6QPdA9gD5APmA9gD5gPaA9MD3wPhA9MD4QPVA8sD2wPdA8sD3QPNA8gD2APaA8gD2gPKA8MD0wPVA8MD1QPFA2cEywPNA2cEzQMFBMADyAPKA8ADygPCA7sDwwPFA7sDxQO9A7gDwAPCA7gDwgO6A7MDuwO9A7MDvQO1A7ADuAO6A7ADugOyA6sDswO1A6sDtQOtA6gDsAOyA6gDsgOqA6QDqwOtA6QDrQOmA6ADqAOqA6ADqgOiA5wDpAOmA5wDpgOeA5gDoAOiA5gDogOaA5QDnAOeA5QDngOWA48DmAOaA48DmgORA4gDlAOWA4gDlgOKA38DjwORA38DkQOBA0YEiAOKA0YEigMCBEEEfwOBA0EEgQMJBIUDPQQ/BIUDPwSDA44DPAREBI4DRASMAz0EOQRHBD0ERwQ/BDwEOARKBDwESgREBDkENgRMBDkETARHBDgENAROBDgETgRKBDYEMgRQBDYEUARMBDQEMARSBDQEUgROBDIELgRUBDIEVARQBDAEKwRVBDAEVQRSBC4EKgRYBC4EWARUBCsEJwRZBCsEWQRVBCoEJgRcBCoEXARYBCcEIwRdBCcEXQRZBCYEIgRgBCYEYARcBCMEHwRhBCMEYQRdBCIEHgRkBCIEZARgBNEDGwRlBNEDZQTPAx8EGQRpBB8EaQRhBB4EGARsBB4EbARkBBsEFQRtBBsEbQRlBBkEEwRvBBkEbwRpBBgEEgRyBBgEcgRsBBUEDwRzBBUEcwRtBBMEDQR1BBMEdQRvBBIEDAR4BBIEeARyBA8EBwR5BA8EeQRzBA0EAwR7BA0EewR1BAwEAAR+BAwEfgR4BAcEhQODAwcEgwN5BAME0QPPAwMEzwN7BAAEjgOMAwAEjAN+BDQDLANWBDQDVgRaBJsCowIvBJsCLwQzBC4DNgO0Ay4DtAOsA6UCnQKdA6UCnQOlAzcDLwNXBDcDVwRbBJcCnwIxBJcCMQQ1BDEDOQO3AzEDtwOvA6ECmQKZA6ECmQOhAzwDNANaBDwDWgReBPsCjQKNA/sCjQP/A5MCmwIzBJMCMwQ3BDYDPgO8AzYDvAO0A4sC/QL9A4sC/QMBBJ0ClQKVA50ClQOdAz8DNwNbBD8DWwRfBPgC0gLSA/gC0gMEBJAClwI1BJACNQQ6BDkDQQO/AzkDvwO3A9AC+gL6A9AC+gMGBJkCkgKSA5kCkgOZA0QDPANeBEQDXgRiBPQChgKGA/QChgMIBIcCkwI3BIcCNwQ7BD4DRgPEAz4DxAO8A4QC9gL2A4QC9gMKBJUCiQKJA5UCiQOVA0cDPwNfBEcDXwRjBO8C+wL/A+8C/wMLBIACkAI6BIACOgQ+BEEDSQPHA0EDxwO/A/0C8QLxA/0C8QP9A5ICggKCA5ICggOSA0wDUgPQA0wD0ANmBOwC+AIEBOwCBAQOBI0ChwI7BI0COwSNA1ADTgPMA1ADzANoBPoC7gLuA/oC7gP6A4kCiwIBBIkCAQSJA1QDRANiBFQDYgRqBOgC9AIIBOgCCAQQBIYCgAI+BIYCPgSGA0YDVgPUA0YD1APEA/YC6gLqA/YC6gP2A4IChAIKBIICCgSCA1cDRwNjBFcDYwRrBOMC7wILBOMCCwQRBEkDWQPXA0kD1wPHA/EC5QLlA/EC5QPxA1wDTANmBFwDZgRuBOAC7AIOBOACDgQUBE4DXgPcA04D3APMA+4C4gLiA+4C4gPuA2ADVANqBGADagRwBNwC6AIQBNwCEAQWBFYDYgPgA1YD4APUA+oC3gLeA+oC3gPqA2MDVwNrBGMDawRxBNcC4wIRBNcCEQQXBFkDZQPjA1kD4wPXA+UC2QLZA+UC2QPlA2gDXANuBGgDbgR0BNQC4AIUBNQCFAQaBF4DagPoA14D6APcA+IC1gLWA+IC1gPiA6QBpQHKAaQBygHIAaUBpgHMAaUBzAHKAaYBpwHOAaYBzgHMAacBqAHRAacB0QHOAagBqQHTAagB0wHRAakBqgHVAakB1QHTAaoBqwHXAaoB1wHVAasBrAHZAasB2QHXAawBrQHbAawB2wHZAa0BrgHdAa0B3QHbAa4BrwHfAa4B3wHdAa8BsAHhAa8B4QHfAbABsQHjAbAB4wHhAbEBsgHlAbEB5QHjAbIBswHnAbIB5wHlAbMBtAHpAbMB6QHnAbQBtQHrAbQB6wHpAbUBtgHtAbUB7QHrAbYBtwHvAbYB7wHtAbcBuAHwAbcB8AHvAbgBuQHyAbgB8gHwAbkBugH0AbkB9AHyAboBuwH2AboB9gH0AbsBvAH4AbsB+AH2AbwBvQH6AbwB+gH4Ab0BvgH8Ab0B/AH6Ab4BvwH+Ab4B/gH8Ab8BoQHCAb8BwgH+AaEBoAHAAaEBwAHCAaABogHEAaABxAHAAesEQAVBBesEQQXuBLYEJgUnBbYEJwW5BIIEDAUNBYIEDQWEBO4EQQVCBe4EQgXwBLkEJwUoBbkEKAW8BIQEDQUOBYQEDgWGBPAEQgVDBfAEQwXyBLwEKAUpBbwEKQW+BIYEDgUPBYYEDwWIBPIEQwVEBfIERAX0BL4EKQUqBb4EKgW/BIgEDwUQBYgEEAWKBPQERAVFBfQERQX2BL8EKgUrBb8EKwXBBIoEEAURBYoEEQWMBPYERQVGBfYERgX5BMEEKwUsBcEELAXDBIwEEQUSBYwEEgWOBPkERgVHBfkERwX7BMMELAUtBcMELQXFBI4EEgUTBY4EEwWQBPsERwVIBfsESAX9BMUELQUuBcUELgXHBJAEEwUUBZAEFAWSBP0ESAVJBf0ESQX/BMcELgUvBccELwXJBJIEFAUVBZIEFQWUBP8ESQVKBf8ESgUBBckELwUwBckEMAXLBJQEFQUWBZQEFgWWBAEFSgVLBQEFSwUDBcsEMAUxBcsEMQXNBJYEFgUXBZYEFwWYBAMFSwVMBQMFTAUGBc0EMQUyBc0EMgXPBJgEFwUYBZgEGAWaBAYFTAVNBQYFTQUIBc8EMgUzBc8EMwXRBJoEGAUZBZoEGQWcBAgFTQVOBQgFTgUKBdEEMwU0BdEENAXTBJwEGQUaBZwEGgWeBAoFTgULBQoFCwWABNMENAU1BdMENQXVBJ4EGgUbBZ4EGwWgBNUENQU2BdUENgXXBKAEGwUcBaAEHAWiBNcENgU3BdcENwXZBKIEHAUdBaIEHQWkBNkENwU4BdkEOAXbBKQEHQUeBaQEHgWmBNsEOAU5BdsEOQXdBKYEHgUfBaYEHwWnBN0EOQU6Bd0EOgXfBKcEHwUgBacEIAWpBN8EOgU7Bd8EOwXhBKkEIAUhBakEIQWsBOEEOwU8BeEEPAXjBKwEIQUiBawEIgWvBOMEPAU9BeMEPQXlBK8EIgUjBa8EIwWxBOUEPQU+BeUEPgXnBLEEIwUkBbEEJAWyBOcEPgU/BecEPwXpBLIEJAUlBbIEJQW0BOkEPwVABekEQAXrBLQEJQUmBbQEJgW2BIAECwUMBYAEDAWCBD8FtwW5BT8FuQVABSUFgwWFBSUFhQUmBQsFUAVSBQsFUgUMBUAFuQW7BUAFuwVBBSYFhQWHBSYFhwUnBQwFUgVUBQwFVAUNBUEFuwW9BUEFvQVCBScFhwWJBScFiQUoBQ0FVAVWBQ0FVgUOBUIFvQW/BUIFvwVDBSgFiQWLBSgFiwUpBQ4FVgVYBQ4FWAUPBUMFvwXBBUMFwQVEBSkFiwWNBSkFjQUqBQ8FWAVaBQ8FWgUQBUQFwQXDBUQFwwVFBSoFjQWPBSoFjwUrBRAFWgVcBRAFXAURBUUFwwXGBUUFxgVGBSsFjwWRBSsFkQUsBREFXAVeBREFXgUSBUYFxgXIBUYFyAVHBSwFkQWTBSwFkwUtBRIFXgVgBRIFYAUTBUcFyAXKBUcFygVIBS0FkwWVBS0FlQUuBRMFYAViBRMFYgUUBUgFygXMBUgFzAVJBS4FlQWXBS4FlwUvBRQFYgVkBRQFZAUVBUkFzAXOBUkFzgVKBS8FlwWZBS8FmQUwBRUFZAVmBRUFZgUWBUoFzgXQBUoF0AVLBTAFmQWbBTAFmwUxBRYFZgVoBRYFaAUXBUsF0AXSBUsF0gVMBTEFmwWdBTEFnQUyBRcFaAVqBRcFagUYBUwF0gXUBUwF1AVNBTIFnQWfBTIFnwUzBRgFagVsBRgFbAUZBU0F1AXWBU0F1gVOBTMFnwWhBTMFoQU0BRkFbAVuBRkFbgUaBU4F1gVQBU4FUAULBTQFoQWjBTQFowU1BRoFbgVwBRoFcAUbBTUFowWlBTUFpQU2BRsFcAVyBRsFcgUcBTYFpQWnBTYFpwU3BRwFcgV0BRwFdAUdBTcFpwWpBTcFqQU4BR0FdAV2BR0FdgUeBTgFqQWrBTgFqwU5BR4FdgV4BR4FeAUfBTkFqwWtBTkFrQU6BR8FeAV6BR8FegUgBToFrQWvBToFrwU7BSAFegV8BSAFfAUhBTsFrwWxBTsFsQU8BSEFfAV+BSEFfgUiBTwFsQWzBTwFswU9BSIFfgWABSIFgAUjBT0FswW1BT0FtQU+BSMFgAWBBSMFgQUkBT4FtQW3BT4FtwU/BSQFgQWDBSQFgwUlBa4FlAaYBq4FmAawBXkFLgYzBnkFMwZ7BbAFmAacBrAFnAayBXsFMwY3BnsFNwZ9BbIFnAagBrIFoAa0BX0FNwY7Bn0FOwZ/BbQFoAakBrQFpAa2BX8FOwY9Bn8FPQaCBbYFpAaoBrYFqAa4BYIFPQZBBoIFQQaEBbgFqAasBrgFrAa6BYQFQQZEBoQFRAaGBU8F2gXeBU8F3gVRBboFrAawBroFsAa8BYYFRAZIBoYFSAaIBVEF3gXiBVEF4gVTBbwFsAa0BrwFtAa+BYgFSAZMBogFTAaKBVMF4gXmBVMF5gVVBb4FtAa4Br4FuAbABYoFTAZQBooFUAaMBVUF5gXqBVUF6gVXBcAFuAa8BsAFvAbCBYwFUAZUBowFVAaOBVcF6gXuBVcF7gVZBcIFvAbABsIFwAbEBY4FVAZYBo4FWAaQBVkF7gXyBVkF8gVbBcQFwAbFBsQFxQbFBZAFWAZcBpAFXAaSBVsF8gX2BVsF9gVdBcUFxQbJBsUFyQbHBZIFXAZgBpIFYAaUBV0F9gX6BV0F+gVfBccFyQbOBscFzgbJBZQFYAZkBpQFZAaWBV8F+gX+BV8F/gVhBckFzgbSBskF0gbLBZYFZAZoBpYFaAaYBWEF/gUCBmEFAgZjBcsF0gbXBssF1wbNBZgFaAZsBpgFbAaaBWMFAgYGBmMFBgZlBc0F1wbbBs0F2wbPBZoFbAZwBpoFcAacBWUFBgYKBmUFCgZnBc8F2wbgBs8F4AbRBZwFcAZ0BpwFdAaeBWcFCgYOBmcFDgZpBdEF4AblBtEF5QbTBZ4FdAZ4Bp4FeAagBWkFDgYRBmkFEQZrBdMF5QbpBtMF6QbVBaAFeAZ8BqAFfAaiBWsFEQYVBmsFFQZtBdUF6QbaBdUF2gVPBaIFfAaABqIFgAakBW0FFQYZBm0FGQZvBaQFgAaEBqQFhAamBW8FGQYdBm8FHQZxBaYFhAaIBqYFiAaoBXEFHQYhBnEFIQZzBagFiAaMBqgFjAaqBXMFIQYmBnMFJgZ1BaoFjAaQBqoFkAasBXUFJgYqBnUFKgZ3BawFkAaUBqwFlAauBXcFKgYuBncFLgZ5BegG5AZYAuEG3AZWAuEGVgJYAt0G2AZXAtgG1AZVAtgGVQJXAtMGzwZUAs8GywZSAs8GUgJUAssGxgZQAssGUAJSAsYGwQZQAsEGvQZPAsEGTwJQAr0GuQZNAr0GTQJPArkGtQZNArUGsQZLArUGSwJNArEGrQZLAq0GqQZJAq0GSQJLAqkGpQZJAqUGoQZJAqEGnQZJAp0GmQZHAp0GRwJJApkGlQZHApUGkQZFApUGRQJHApEGjQZFAo0GiQZBAo0GQQJFAokGhQZBAoUGgQZDAoUGQwJBAoEGfQZDAn0GeQZ+An0GfgJDAnkGdQZ8AnkGfAJ+AnUGcQZ8AnEGbQZ6AnEGegJ8Am0GaQZ6AmkGZQZ4AmkGeAJ6AmUGYQZ4AmEGXQZ4Al0GWQZ4AlkGVQZ2AlkGdgJ4AlUGUQZ2AlEGTQZ0AlEGdAJ2Ak0GSQZ0AkkGRgZyAkkGcgJ0AkYGQgZvAkYGbwJyAkIGPwZvAj8GOgZtAj8GbQJvAjoGNgZrAjoGawJtAjYGMgZrAjIGLwZpAjIGaQJrAi8GKwZnAi8GZwJpAisGJwZnAicGIgZnAiMGHgZmAiMGZgJoAh4GGgZmAhoGFgZmAhYGEgZmAhIGDQZkAhIGZAJmAg0GCQZkAgkGBQZiAgkGYgJkAgUGAQZiAgEG/QVgAgEGYAJiAv0F+QVgAvkF9QVeAvkFXgJgAvUF8QVeAvEF7QVeAu0F6QVcAu0FXAJeAukF5QVcAuUF4QVaAuUFWgJcAuEF3QVaAt0F2QVaAtkF6AZYAtkFWAJaAusF5wVyB+sFcgd0B+wE7QRYB+wEWAdWB7cEugQkB7cEJAchB4EEgwTvBoEE7wbtBu0E7wRaB+0EWgdYB7gEuwQmB7gEJgcjB4MEhQTxBoME8QbvBu8E8QRcB+8EXAdaB7sEvQQoB7sEKAcmB4UEhwTzBoUE8wbxBvME9QRgB/MEYAddB70EwAQqB70EKgcoB4cEiQT1BocE9QbzBvUE9wRiB/UEYgdgB8AEwgQsB8AELAcqB4kEiwT3BokE9wb1BvcE+ARkB/cEZAdiB8IExAQuB8IELgcsB4sEjQT5BosE+Qb3BvgE+gRmB/gEZgdkB8QExgQwB8QEMAcuB40EjwT7Bo0E+wb5BvoE/ARoB/oEaAdmB8YEyAQyB8YEMgcwB48EkQT9Bo8E/Qb7BvwE/gRqB/wEagdoB8gEygQ0B8gENAcyB5EEkwT/BpEE/wb9BgAFAgVtBwAFbQdrB8oEzAQ2B8oENgc0B5MElQQBB5MEAQf/BgIFBAVvBwIFbwdtB8wEzgQ4B8wEOAc2B5UElwQDB5UEAwcBBwQFBQVxBwQFcQdvB84E0AQ6B84EOgc4B5cEmQQFB5cEBQcDBwUFBwVzBwUFcwdxB9AE0gQ8B9AEPAc6B5kEmwQHB5kEBwcFBwcFCQV1BwcFdQdzB9IE1AQ+B9IEPgc8B5sEnQQJB5sECQcHBwkFfwTrBgkF6wZ1B9QE1gRAB9QEQAc+B50EnwQLB50ECwcJB9YE2ARCB9YEQgdAB58EoQQNB58EDQcLB9gE2gREB9gERAdCB6EEowQPB6EEDwcNB9oE3ARGB9oERgdEB6MEpQQRB6MEEQcPB9wE3gRIB9wESAdGB6UEqAQTB6UEEwcRB94E4ARKB94ESgdIB6gEqgQVB6gEFQcTB+AE4gRMB+AETAdKB6oErQQYB6oEGAcVB+IE5AROB+IETgdMB6sErgQZB6sEGQcXB+QE5gRQB+QEUAdOB64EsAQbB64EGwcZB+YE6ARSB+YEUgdQB7AEswQdB7AEHQcbB+gE6gRUB+gEVAdSB7MEtQQfB7MEHwcdB+oE7ARWB+oEVgdUB7UEtwQhB7UEIQcfB38EgQTtBn8E7QbrBucF4wVwB+cFcAdyB+MF3wVuB+MFbgdwB98F2wVsB98FbAduB9sF1wVpB9sFaQdsB9cF5gZnB9cFZwdpB+YG4gZlB+YGZQdnB+IG3gZjB+IGYwdlB94G2QZhB94GYQdjB9kG1QZfB9kGXwdhB9UG0AZeB9UGXgdfB9AGzQZbB9AGWwdeB80GygZZB80GWQdbB8oGxwZXB8oGVwdZB8cGwwZVB8cGVQdXB8MGvwZTB8MGUwdVB78GuwZRB78GUQdTB7sGtwZPB7sGTwdRB7cGswZNB7cGTQdPB7MGrwZLB7MGSwdNB68GqwZJB68GSQdLB6sGpwZHB6sGRwdJB6cGowZFB6cGRQdHB6MGnwZDB6MGQwdFB58GmwZBB58GQQdDB5sGlwY/B5sGPwdBB5cGkwY9B5cGPQc/B5MGjwY7B5MGOwc9B48GiwY5B48GOQc7B4sGhwY3B4sGNwc5B4cGgwY1B4cGNQc3B4MGfwYzB4MGMwc1B38GewYxB38GMQczB3sGdwYvB3sGLwcxB3cGcwYtB3cGLQcvB3MGbwYrB3MGKwctB28GawYpB28GKQcrB2sGZwYnB2sGJwcpB2cGYwYlB2cGJQcnB2MGXwYiB2MGIgclB18GWwYgB18GIAciB1sGVwYeB1sGHgcgB1cGUwYcB1cGHAceB1MGTwYaB1MGGgccB08GSgYWB08GFgcaB0oGRQYUB0oGFAcWB0UGQAYSB0UGEgcUB0AGPAYQB0AGEAcSBzwGOAYOBzwGDgcQBzgGNAYMBzgGDAcOBzQGMAYKBzQGCgcMBzAGLAYIBzAGCAcKBywGKAYGBywGBgcIBygGJAYEBygGBAcGByQGHwYCByQGAgcEBx8GGwYABx8GAAcCBxsGFwb+BhsG/gYABxcGEwb8BhcG/Ab+BhMGDwb6BhMG+gb8Bg8GCwb4Bg8G+Ab6BgsGBwb2BgsG9gb4BgcGAwb0BgcG9Ab2BgMG/wXyBgMG8gb0Bv8F+wXwBv8F8AbyBvsF9wXuBvsF7gbwBvcF8wXsBvcF7AbuBvMF7wXqBvMF6gbsBu8F6wV0B+8FdAfqBuMG5wbYBdgF3AXgBeAF5AXoBegF7AXwBfAF9AX4BfgF/AUABgAGBAYIBggGDAYQBhAGFAYYBhgGHAYgBiAGJQYpBikGLQYxBjEGNQY5BjkGPgZDBkMGRwZLBksGTgZSBlIGVgZaBloGXgZiBmIGZgZqBmoGbgZyBnIGdgZ6BnoGfgaCBoIGhgaKBooGjgaSBpIGlgaaBpoGngaiBqIGpgaqBqoGrgayBrIGtga6BroGvgbCBsIGxAbIBsgGzAbRBtEG1gbaBtoG3wbjBuMG2AXgBeAF6AXwBfAF+AUABgAGCAYQBhAGGAYgBiAGKQYxBjEGOQZDBkMGSwZSBlIGWgZiBmIGagZyBnIGegaCBoIGigaSBpIGmgaiBqIGqgayBrIGugbCBsIGyAbRBtEG2gbjBuMG4AXwBfAFAAYQBhAGIAYxBjEGQwZSBlIGYgZyBnIGggaSBpIGogayBrIGwgbRBtEG4wbwBfAFEAYxBjEGUgZyBnIGkgayBrIG0QbwBfAFMQZyBvAFcgayBg==" + } + ] +} diff --git a/frontend/src/assets/models/gltf-glb/crate_box.glb b/frontend/src/assets/models/gltf-glb/crate_box.glb new file mode 100644 index 0000000..df4175b Binary files /dev/null and b/frontend/src/assets/models/gltf-glb/crate_box.glb differ diff --git a/frontend/src/assets/models/gltf-glb/door.glb b/frontend/src/assets/models/gltf-glb/door.glb new file mode 100644 index 0000000..f2a73e1 Binary files /dev/null and b/frontend/src/assets/models/gltf-glb/door.glb differ diff --git a/frontend/src/assets/models/gltf-glb/sofa.glb b/frontend/src/assets/models/gltf-glb/sofa.glb new file mode 100644 index 0000000..2512e7c Binary files /dev/null and b/frontend/src/assets/models/gltf-glb/sofa.glb differ diff --git a/frontend/src/assets/models/gltf-glb/window.glb b/frontend/src/assets/models/gltf-glb/window.glb new file mode 100644 index 0000000..27ea80e Binary files /dev/null and b/frontend/src/assets/models/gltf-glb/window.glb differ diff --git a/frontend/src/assets/models/note.txt b/frontend/src/assets/models/note.txt new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/assets/styles/abstracts/_functions.scss b/frontend/src/assets/styles/abstracts/_functions.scss new file mode 100644 index 0000000..6f0745d --- /dev/null +++ b/frontend/src/assets/styles/abstracts/_functions.scss @@ -0,0 +1,5 @@ +// get rem from pixels + +@function get_rem($px) { + @return calc($px / 16 * 1rem); +} diff --git a/frontend/src/assets/styles/abstracts/_mixins.scss b/frontend/src/assets/styles/abstracts/_mixins.scss new file mode 100644 index 0000000..ac29f00 --- /dev/null +++ b/frontend/src/assets/styles/abstracts/_mixins.scss @@ -0,0 +1,11 @@ +@mixin flex-center { + display: flex; + justify-content: center; + align-items: center; +} + +@mixin flex-space-between { + display: flex; + justify-content: space-between; + align-items: center; +} diff --git a/frontend/src/assets/styles/abstracts/_placeholders.scss b/frontend/src/assets/styles/abstracts/_placeholders.scss new file mode 100644 index 0000000..28dc1ef --- /dev/null +++ b/frontend/src/assets/styles/abstracts/_placeholders.scss @@ -0,0 +1,6 @@ +// center a element +%centered { + display: flex; + justify-content: center; + align-items: center; +} diff --git a/frontend/src/assets/styles/abstracts/_variables.scss b/frontend/src/assets/styles/abstracts/_variables.scss new file mode 100644 index 0000000..ecdaa9e --- /dev/null +++ b/frontend/src/assets/styles/abstracts/_variables.scss @@ -0,0 +1,31 @@ +@use "functions"; + +// colors +$primary-color: hsl(0, 0%, 100%); +$text-gray: #969BA7; +$selected-text-gray: #828282; +$button-action-color: #5c87df; +$button-abort-color: #ffffff; +$secondary-color: #5c87df; +$accent-color: #5c87df; +$lite-gray-40: #d9d9d9; +$lite-gray-80: #828282; +$border-color: #c1c1c1; +$border-color-20: #c1c1c133; +$highlight-light-color: #f0f0f0; +$button-hover-color: #e7e7e8; + +// icon colors +$icon-idle-color: #5D5F63; + +//font sizes +$font-size-small: functions.get_rem(12); +$font-size-default: functions.get_rem(14); +$font-size-title: functions.get_rem(16); +$font-size-header: functions.get_rem(24); + +$font-weight-semi: 400; +$font-weight-regular: 500; + +// Shadow +$shadow-main: 0px 2px 10px 0px #0000001c; \ No newline at end of file diff --git a/frontend/src/assets/styles/base/_base.scss b/frontend/src/assets/styles/base/_base.scss new file mode 100644 index 0000000..c345fa8 --- /dev/null +++ b/frontend/src/assets/styles/base/_base.scss @@ -0,0 +1,81 @@ +@use "../abstracts/variables"; + +[data-theme="light"] { + --primary-color: #{variables.$primary-color}; + --text-gray: #{variables.$text-gray}; + --selected-text-gray: #{variables.$selected-text-gray}; + --button-action-color: #{variables.$button-action-color}; + --button-abort-color: #{variables.$button-abort-color}; + --secondary-color: #{variables.$secondary-color}; + --accent-color: #{variables.$accent-color}; + --lite-gray-40: #{variables.$lite-gray-40}; + --lite-gray-80: #{variables.$lite-gray-80}; + --border-color: #{variables.$border-color}; + --border-color-20: #{variables.$border-color-20}; + --highlight-light-color: #{variables.$highlight-light-color}; + --button-hover-color: #{variables.$button-hover-color}; + + //shadow variables + --shadow-main: #{variables.$shadow-main}; + + //icon colors + --icon-idle-color: #{variables.$icon-idle-color}; + +} + +[data-theme="dark"] { + --primary-color: #{variables.$primary-color}; + --text-gray: #{variables.$text-gray}; + --selected-text-gray: #{variables.$selected-text-gray}; + --button-action-color: #{variables.$button-action-color}; + --button-abort-color: #{variables.$button-abort-color}; + --secondary-color: #{variables.$secondary-color}; + --accent-color: #{variables.$accent-color}; + --lite-gray-40: #{variables.$lite-gray-40}; + --lite-gray-80: #{variables.$lite-gray-80}; + --border-color: #{variables.$border-color}; + --border-color-20: #{variables.$border-color-20}; + --highlight-light-color: #{variables.$highlight-light-color}; + + //shadow variables + --shadow-main: #{variables.$shadow-main}; +} + +#root { + height: 100vh; + width: 100vw; + overflow: hidden; +} + +#root-over { + position: fixed; + top: 0; + left: 0; + z-index: 99; +} + +.selected, +.select { + background-color: var(--secondary-color) !important; + color: var(--primary-color); + border-radius: 6px; + overflow: hidden; + text-overflow: ellipsis; + text-wrap: nowrap; + padding: 4px; + + .key { + color: var(--primary-color); + } + + &:hover { + outline: none; + border: none; + background-color: var(--secondary-color); + } +} + + +.active { + color: var(--secondary-color) !important; +} \ No newline at end of file diff --git a/frontend/src/assets/styles/base/_reset.scss b/frontend/src/assets/styles/base/_reset.scss new file mode 100644 index 0000000..b0d8fff --- /dev/null +++ b/frontend/src/assets/styles/base/_reset.scss @@ -0,0 +1,6 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + user-select: none; +} diff --git a/frontend/src/assets/styles/base/_typography.scss b/frontend/src/assets/styles/base/_typography.scss new file mode 100644 index 0000000..7a22740 --- /dev/null +++ b/frontend/src/assets/styles/base/_typography.scss @@ -0,0 +1,25 @@ +@use "../abstracts/variables"; + +// local fonts imports and decleration + +@font-face { + font-family: "Inter"; + src: url("../../fonts/inter/inter18ptRegular.ttf") format("truetype"); +} + +@font-face { + font-family: "Poppins"; + src: url("../../fonts/poppins/poppinsRegular.ttf") format("truetype"); +} + +@font-face { + font-family: "Roboto"; + src: url("../../fonts/roboto/robotoRegular.ttf") format("truetype"); +} + +* { + font-family: "Inter", sans-serif; + font-weight: variables.$font-weight-regular; + font-size: variables.$font-size-default; + color: var(--text-gray); +} \ No newline at end of file diff --git a/frontend/src/assets/styles/components/_card.scss b/frontend/src/assets/styles/components/_card.scss new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/assets/styles/components/_toogleSwitch.scss b/frontend/src/assets/styles/components/_toogleSwitch.scss new file mode 100644 index 0000000..c7e59a5 --- /dev/null +++ b/frontend/src/assets/styles/components/_toogleSwitch.scss @@ -0,0 +1,128 @@ +// .content-container { +// height: calc(100vh - 82px); +// height: 100%; +// margin-top: 6px; +// } + +.switches { + width: 100%; + height: 100%; + min-width: 100px; + flex-direction: column; + align-items: baseline; + // position: fixed; + // top: 0; +} + +.switch-tools { + position: absolute; + width: 100%; + gap: 20px; + padding: 20px; + + .project_toolbar-left { + gap: 16px; + } +} + +.toggle-container { + // display: flex; + // justify-content: center; + // align-items: center; + user-select: none; +} + +.toggle-switch { + // min-width: 80px; + + height: 30px; + box-shadow: 0px 2px 10px 0px #0000001c; + + border-radius: 10px; + position: relative; + cursor: pointer; + // display: flex; + // align-items: center; + // justify-content: space-between; + padding: 0; + transition: background-color 0.3s ease; + overflow: hidden; +} + +.toggle-switch.am { + background-color: #ffffff; + /* AM - blue */ + // margin: 0px 10px; + + /* background:red; */ +} + +.toggle-switch.pm { + background-color: #ffffff; + /* PM - orange */ +} + +.am-label, +.pm-label { + color: $selected-text-gray; + font-size: 12px; + width: 50%; + text-align: center; + position: relative; + z-index: 2; + padding: 5px 10px; + /* Ensure labels stay above the knob */ +} + +.toggle-knob { + width: 50%; + height: 100%; + background-color: $button-action-color; + border-radius: 8px; + position: absolute; + transition: transform 0.3s ease; + z-index: 1; + /* Ensure knob is under the labels */ +} + +.toggle-switch.pm .toggle-knob { + transform: translateX(100%); +} + +.upload { + height: 30px; + background-color: $primary-color; + position: relative; + /* Necessary for absolute positioning */ +} + +.upload input[type="file"] { + position: absolute; + width: 100%; + height: 100%; + opacity: 0; + cursor: pointer; + /* Show a pointer cursor on hover */ +} + +.upload span { + z-index: 1; + /* Ensure the text is above the file input */ +} + +.upload .UploadIcon { + display: none; + /* Hide the UploadIcon component */ +} + +/* Optional: Additional styling for better appearance */ +.upload { + padding: 10px 20px; + border-radius: 8px; + /* Rounded corners */ +} + +.upload:hover { + background-color: #e0e0e0; + /* Change background color on hover */ +} \ No newline at end of file diff --git a/frontend/src/assets/styles/components/_undoRedo.scss b/frontend/src/assets/styles/components/_undoRedo.scss new file mode 100644 index 0000000..1914ac9 --- /dev/null +++ b/frontend/src/assets/styles/components/_undoRedo.scss @@ -0,0 +1,51 @@ +.undoRedo { + background-color: var(--primary-color); + box-shadow: var(--shadow-main); + height: 30px; + border-radius: 10px; + position: relative; + justify-content: space-around; + pointer-events: all; + gap: 0 !important; + overflow: hidden; +} + +.split { + height: 50%; + width: 2px; + background: var(--lite-gray-40); +} + +.icon { + height: 100%; + display: flex; + align-items: center; + cursor: pointer; + height: 100%; + padding: 6px; + + + svg { + scale: 0.8; + } + + &:hover { + background-color: var(--button-hover-color); + + path { + fill: var(--secondary-color); + stroke: var(--secondary-color); + stroke-width: .5px; + } + } + + &::after { + content: ""; + position: absolute; + width: 1px; + height: 20px; + left: calc(50% - 0.5px); + top: 50%; + transform: translateY(-50%); + } +} \ No newline at end of file diff --git a/frontend/src/assets/styles/components/inputs/_button.scss b/frontend/src/assets/styles/components/inputs/_button.scss new file mode 100644 index 0000000..816f010 --- /dev/null +++ b/frontend/src/assets/styles/components/inputs/_button.scss @@ -0,0 +1,23 @@ +// text buttons + +.button, +button { + border: none; + outline: none; + background-color: var(--button-action-color); + color: var(--primary-color); + border-radius: 6px; + padding: 6px 15px; + box-shadow: var(--shadow-main); + cursor: pointer; +} + +// icon buttons + +.tools { + width: 28.8px; + height: 28.8px; + border-radius: 7.01px; + background-color: var(--primary-color); + box-shadow: 0px 1.92px 9.6px 0px #0000001c; +} \ No newline at end of file diff --git a/frontend/src/assets/styles/components/inputs/_dropDown.scss b/frontend/src/assets/styles/components/inputs/_dropDown.scss new file mode 100644 index 0000000..3844b11 --- /dev/null +++ b/frontend/src/assets/styles/components/inputs/_dropDown.scss @@ -0,0 +1,104 @@ +.dropdown-container { + width: 104px; + height: 30px; + position: relative; + box-shadow: var(--shadow-main); + background-color: var(--primary-color); + border-radius: 10px; + justify-content: space-between; + padding: 10px; + pointer-events: all; +} + +.dropdown-toggle { + width: 100%; + background-color: #fff; + border-radius: 4px; + cursor: pointer; + color: var(--selected-text-gray); + font-size: var(--font-size-small); +} + +.dropdown-menu { + user-select: none; + width: 237px; + position: absolute; + background-color: #fff; + box-shadow: var(--shadow-main); + border-radius: 4px; + z-index: 1000; + margin-top: 2px; + overflow-y: auto; + top: 110%; + left: 50%; + transform: translate(-21%, 0); + // padding: 10px 0; + // padding-top: 0; + + .dropDown-header { + border-bottom: 1px solid var(--border-color-20); + height: 40px; + padding: 0 17px; + } + + .dropdown-menu { + user-select: none; + width: 237px; + position: absolute; + background-color: #fff; + box-shadow: var(var(--shadow-main)); + border-radius: 4px; + z-index: 1000; + margin-top: 2px; + overflow-y: auto; + top: 110%; + left: 50%; + transform: translate(-21%, 0); + // padding: 10px 0; + // padding-top: 0; + + .dropDown-header { + border-bottom: 1px solid var(--border-color-20); + height: 40px; + padding: 0 17px; + } + } + .selected { + path{ + stroke: var(--primary-color); + fill: transparent; + stroke-width: 2px; + &:last-child{ + stroke-width: 1px; + } + } + .left { + color: var(--primary-color); + input[type=checkbox]{ + + } + } + } + .dropdown-option { + padding: 10px 0; + cursor: pointer; + justify-content: flex-start; + justify-content: space-between; + align-items: center; + padding: 10px 17px; + + .right { + .icons { + width: 14px; + height: 14px; + } + } + &:hover { + background-color: var(--highlight-light-color); + } + } + + li { + list-style: none; + } +} diff --git a/frontend/src/assets/styles/components/inputs/_inputs.scss b/frontend/src/assets/styles/components/inputs/_inputs.scss new file mode 100644 index 0000000..f307283 --- /dev/null +++ b/frontend/src/assets/styles/components/inputs/_inputs.scss @@ -0,0 +1,35 @@ +input, +textarea { + border: none; + outline: 1px solid var(--lite-gray-40); + border-radius: 4px; + padding: 2px 4px; + resize: none; + + &:active, + &:focus { + outline: 1px solid var(--secondary-color); + } +} + + +input[type="checkbox"] { + border: none; + outline: none; + accent-color: var(--accent-color); +} + +input[type="range"] { + border: none; + outline: none; + + &:active, + &:focus { + outline: none; + } +} + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + -webkit-appearance: none; +} \ No newline at end of file diff --git a/frontend/src/assets/styles/components/inputs/_popup.scss b/frontend/src/assets/styles/components/inputs/_popup.scss new file mode 100644 index 0000000..8a1225a --- /dev/null +++ b/frontend/src/assets/styles/components/inputs/_popup.scss @@ -0,0 +1,175 @@ +@use "../../abstracts/variables"; + +.collaboration-settings-wrapper, +.remove-user-popup-wrapper { + width: 100vw; + height: 100vh; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + // background: #1F1F1F4D; + + background-color: #1F1F1F4D; + display: flex; + justify-content: center; + align-items: center; + + .collaboration-settings-container, + .remove-menu-container { + display: flex; + flex-direction: column; + gap: 18px; + background-color: variables.$button-abort-color; + padding: 20px; + border-radius: 8px; + + .menu-header-wrapper { + // display: flex; + width: 100%; + justify-content: space-between; + + .menu-header { + h2 { + color: variables.$secondary-color ; + font-weight: 500; + font-size: variables.$font-size-title; + } + } + + .close-button { + width: 16px; + line-height: 15px; + border: 1px solid #635D5D; + border-radius: 50%; + + font-size: 10px; + color: #635D5D; + + display: flex; + justify-content: center; + align-items: center; + + cursor: pointer; + } + } + + + .add-new-collab-user-wrapper { + position: relative; + + border: 1px solid #DADADA; + width: 100%; + height: 40px; + background: #D9D9D903; + border-radius: 6px; + + .searchInput { + width: 62%; + height: 100%; + background: transparent; + padding: 0 10px; + border: none; + outline: none; + } + + .access-control-dropdown, + .addMember { + position: absolute; + top: 50%; + right: 100px; + transform: translate(0%, -50%); + cursor: pointer; + } + + .addMember { + border: none; + outline: none; + background: transparent; + padding: 0; + right: 5px; + } + } + + + .list-users-in-collab-project-wrapper { + + width: 100%; + border-top: 1px solid #F2F2F2; + border-bottom: 1px solid #F2F2F2; + padding: 20px 0; + + .list-users-in-collab-project { + width: 100%; + + .collab-users { + + width: 100%; + display: flex; + flex-direction: column-reverse; + gap: 10px; + + .users { + width: 100%; + display: flex; + justify-content: space-between; + + .users-wrapper { + + display: flex; + align-items: center; + gap: 8px; + + .collab-user-profile { + width: 20px; + height: 20px; + + background: #5C87DF4D; + color: #5C87DF; + + border: 1px solid #DADADA; + border-radius: 50%; + + display: flex; + justify-content: center; + align-items: center; + text-transform: uppercase; + + padding: 0; + margin: 0; + } + } + + .edit-remove { + display: flex; + align-items: center; + gap: 20px; + + .edit-button, + .remove-button { + cursor: pointer; + } + } + } + } + } + } + + + + + // confirm popup + .menu-header-wrapper {} + + .menu-conformation-wrapper { + display: flex; + justify-content: flex-end; + gap: 20px; + + input[type="button"] { + padding: 5px 10px; + cursor: pointer; + } + } + } +} \ No newline at end of file diff --git a/frontend/src/assets/styles/components/sideBar/_basic.scss b/frontend/src/assets/styles/components/sideBar/_basic.scss new file mode 100644 index 0000000..693b149 --- /dev/null +++ b/frontend/src/assets/styles/components/sideBar/_basic.scss @@ -0,0 +1,251 @@ +@use "../../abstracts/variables"; + +.object-header { + width: 100%; + + .head { + padding: 5px; + cursor: pointer; + } + + .active { + border-bottom: 1px solid variables.$secondary-color; + } +} + + +.object-wrapper { + .basic-properties { + display: flex; + flex-direction: column; + gap: 15px; + width: 100%; + + .transform, + .easing-container, + .time-management, + .state-management, + .basic-properties { + width: 100%; + border-bottom: 1px solid variables.$border-color-20; + padding-bottom: 18px; + + display: flex; + flex-direction: column; + gap: 10px; + + + .icons { + cursor: pointer; + } + } + + // Time Management & Global Properties + .time-management, + .global-properties { + width: 100%; + display: flex; + flex-direction: column; + gap: 10px; + + + .icons { + transition: transform 0.3s ease; + } + + .icons.rotate { + transform: rotate(90deg); + } + + .data-wrapper { + display: flex; + flex-direction: column; + gap: 8px; + + .data { + display: flex; + + .left { + width: 100px; + + input { + width: 100%; + text-align: center; + } + } + } + + + } + + + + // .format-section { + // .data-wrapper { + // .data { + // display: flex; + // flex-direction: column; + // align-items: flex-start; + + // .header { + // border: none; + // } + + // .input-wrapper { + // display: flex; + // gap: 5px; + + // .input-group { + // display: flex; + // align-items: center; + + // .data { + // flex-direction: row; + // align-items: center; + + // .left { + // height: 26px; + // position: relative; + // width: 51px; + // border: 1px solid $highlight-light-color; + // border-radius: 6px; + + // input { + // width: 100%; + // height: 100%; + // position: absolute; + // } + + // .icon { + // position: relative; + // z-index: 100; + + // &:hover { + // background: none; + // } + // } + // } + // } + // } + // } + // } + // } + // } + } + + + .easing-container { + .easing-header { + width: 100%; + } + + .left { + + width: 100%; + } + } + + + .state-management-content { + display: flex; + flex-direction: column; + gap: 10px; + + .data-wrapper { + display: flex; + flex-direction: column; + gap: 6px; + + .data { + padding: 4px; + } + + .selected { + background-color: #E5ECFA !important; + + .key { + color: #5C87DF; + font-weight: 500; + } + } + } + } + + .header { + border: none; + } + + .icons { + + transition: all linear 0.2s; + } + + .rotate { + transform: rotate(90deg); + } + } +} + + + + + + + + +// Dropdown Styles +.regularDropdown-container { + width: 104px; + height: 22px; + border: 1px solid variables.$border-color; // Ensure $border-color is defined + border-radius: 6px; + position: relative; + cursor: pointer; + + .dropdown-header { + height: 100%; + display: flex; + justify-content: space-between; + cursor: pointer; + padding: 5px; + border: 1px solid variables.$highlight-light-color; + border-radius: 6px; + background-color: variables.$primary-color; + + .icon { + position: absolute; + right: 0; + padding: 3px; + } + } + + .dropdown-options { + position: absolute; // Ensure dropdown options position correctly + width: 100%; // Ensure options width matches the header + background-color: variables.$primary-color; // Optional: Background color + border: 1px solid #ccc; // Optional: Border styling + border-radius: 4px; // Optional: Border radius + z-index: 10; // Ensure dropdown appears above other elements + max-height: 200px; // Optional: Limit height + overflow-y: auto; // Optional: Enable scrolling if content exceeds height + + .option { + padding: 5px; + cursor: pointer; + + &:hover { + background-color: variables.$highlight-light-color; // Optional: Hover effect + } + } + } + + .icon { + height: auto; + } +} + + + +.icon { + cursor: pointer; +} \ No newline at end of file diff --git a/frontend/src/assets/styles/components/sideBar/_basicGlobal.scss b/frontend/src/assets/styles/components/sideBar/_basicGlobal.scss new file mode 100644 index 0000000..268ecaf --- /dev/null +++ b/frontend/src/assets/styles/components/sideBar/_basicGlobal.scss @@ -0,0 +1,147 @@ +@use "../../abstracts/variables"; + +// Time Management & Global Properties +.global-properties { + width: 100%; + display: flex; + flex-direction: column; + gap: 10px; + + .icons { + cursor: pointer; + } + + .section { + display: flex; + flex-direction: column; + gap: 12px; + + border-bottom: 1px solid variables.$border-color; + padding-bottom: 16px; + } + + .icons { + transition: transform 0.3s ease; + } + + .icons.rotate { + transform: rotate(90deg); + } + + .data-wrapper { + display: flex; + flex-direction: column; + gap: 10px; + + .data { + .header { + padding: 0; + padding-bottom: 8px; + border: none; + } + + .input-wrapper { + display: flex; + gap: 20px; + + .input-group { + .data { + .header { + background-color: red; + padding-bottom: 6px; + } + + .left { + position: relative; + + width: 51px; + + .icon { + position: absolute; + // left: 0; + + &:last-child { + right: 0; + } + } + } + } + + display: flex; + + .data { + justify-content: flex-start; + } + } + } + + .left { + width: 100px; + + input { + width: 100%; + text-align: center; + } + } + } + } +} + + + + +// Transform Section +.transform { + display: flex; + flex-direction: column; + gap: 12px; + border-bottom: 1px solid var(--border-color); + padding-bottom: 18px; + + .icons { + cursor: pointer; + transition: all linear 0.2s; + } + + .rotate { + transform: rotate(90deg); + } + + .objectInput-wrapper { + border: none; + padding-top: 0px; + padding-bottom: 15px; + display: flex; + flex-direction: column; + gap: 10px; + width: 100%; + gap: 15px; + border: none; + + .objectInputcontent-wrapper { + + display: flex; + flex-direction: column; + gap: 6px; + } + + .label { + width: 100%; + justify-content: space-between; + } + + .objectInputs { + .object-input { + gap: 6px; + display: flex; + .value { + width: 36px; + + input { + width: 100%; + } + } + } + } + } +} \ No newline at end of file diff --git a/frontend/src/assets/styles/components/sideBar/_data.scss b/frontend/src/assets/styles/components/sideBar/_data.scss new file mode 100644 index 0000000..af419f0 --- /dev/null +++ b/frontend/src/assets/styles/components/sideBar/_data.scss @@ -0,0 +1,144 @@ +.dataSideBar { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + gap: 12px; + + .sideBarHeader { + color: #5c87df; + border-bottom: 1px solid var(--border-color); + padding-bottom: 6px; + } + + .selectedMain-container { + display: flex; + flex-direction: column; + gap: 6px; + border-bottom: 1px solid var(--border-color); + padding-bottom: 10px; + } + + .selectedMain { + display: flex; + // gap: 2px; + align-items: center; + + .icon { + padding: 0; + } + + button { + background-color: transparent; + box-shadow: none; + color: #5273eb; + padding: 6px; + font-size: 18px; + } + + &:first-child { + gap: 4px; + } + + // padding-bottom: 10px; + // border-bottom: 1px solid var(--border-color); + .bulletPoint { + color: #5273eb; + font-size: 16px; + } + + main { + width: 35%; + white-space: nowrap; + /* Prevent wrapping */ + } + + .regularDropdown-container { + width: 100%; + } + } + + .child { + padding-left: 13%; + width: 100%; + gap: 6px; + } + + .horizontalLine { + width: 100%; + border-top: 1px solid #d1d1d1; + /* Horizontal line */ + margin-top: 10px; + } + + .dropdown { + padding: 8px; + font-size: 14px; + border: 1px solid #d1d1d1; + border-radius: 4px; + background: white; + cursor: pointer; + } + + .infoBox { + display: flex; + align-items: flex-start; + gap: 6px; + color: #444; + border-radius: 6px; + font-size: 14px; + + .infoIcon { + padding: 0px 5px; + border-radius: 50%; + border: 1px solid gray; + } + + p { + margin: 0; + } + } +} + + + + +.design { + width: 100%; + display: flex; + flex-direction: column; + gap: 15px; + padding: 0px; + font-size: 14px; + color: #4a4a4a; +} + +.reviewChart { + width: 100%; + height: 150px; + background: #f0f0f0; + border-radius: 8px; +} + +.optionsContainer { + display: flex; + flex-direction: column; + gap: 10px; +} + +.option { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + + .regularDropdown-container { + width: 160px; + } + + span { + min-width: 100px; + } + + +} \ No newline at end of file diff --git a/frontend/src/assets/styles/components/sideBar/_material.scss b/frontend/src/assets/styles/components/sideBar/_material.scss new file mode 100644 index 0000000..5a637b5 --- /dev/null +++ b/frontend/src/assets/styles/components/sideBar/_material.scss @@ -0,0 +1,196 @@ +.material-container { + width: 100%; + display: flex; + flex-direction: column; + gap: 14px; + padding: 8px; + .materialName { + text-align: left; + padding-bottom: 6px; + } + + .canvas { + width: 100%; + height: 106px; + border-radius: 10px; + box-shadow: var(--shadow-main); + } + + .materialSettings { + flex-direction: column; + justify-content: flex-start; + padding: 20px 0; + gap: 15px; + + .material { + width: 100%; + .flex-sb{ + span{ + + width: 20px; + text-align: center; + } + } + .data{ + width: 100%; + .left { + position: relative; + right: -10px; + width: 100px; + input{ + width: 50%; + } + } + } + .flex { + + // width: 60%; + span { + width: 50px; + } + } + } + } +} + +.wrapper { + margin: 4rem; +} + +.input-rangeslider { + position: relative; + width: 100%; +} + +.input-rangeslider:before, +.input-rangeslider:after { + content: ""; + display: block; + position: absolute; + left: 0; + right: 0; + top: 50%; + height: 1px; +} + +.input-rangeslider:before { + background: #6b6f7c; +} + +.input-rangeslider:after { + content: attr(data-value); + font-size: 0.78rem; + line-height: 56px; + text-align: left; + background: #30343f; + left: inherit; + transition: color 0.25s ease-in-out; + color: transparent; + white-space: nowrap; + text-indent: -1.25rem; +} + +.input-rangeslider.show-output:after { + color: white; +} + +input[type="range"] { + -webkit-appearance: none; + width: 80px; + height: 14px; + background: none; + cursor: pointer; + border: none; + color: transparent; + // position: absolute; + z-index: 2; + // top: 50%; + // transform: translateY(-50%); + margin: 0; + padding: 0; +} + +input[type="range"]::-webkit-slider-runnable-track { + appearance: none; + width: 100%; + height: 14px; + background: none; + cursor: pointer; + border: none; + color: transparent; +} + +input[type="range"]::-moz-range-track { + appearance: none; + width: 100%; + height: 14px; + background: none; + cursor: pointer; + border: none; + color: transparent; +} + +input[type="range"]::-ms-track { + appearance: none; + width: 100%; + height: 14px; + background: none; + cursor: pointer; + border: none; + color: transparent; +} + +input[type="range"]::-webkit-slider-thumb { + appearance: none; + border: none; + height: 14px; + width: 14px; + border-radius: 7px; + background: #b7b7b7; + position: relative; + border: 3px solid #5d5d5db2; + cursor: pointer; +} + +input[type="range"]::-moz-range-thumb { + appearance: none; + // box-shadow: 0 0 10px rgba(black, .15); + border: none; + height: 14px; + width: 14px; + border-radius: 7px; + background: white; + cursor: pointer; +} + +/* Continuing Material.css */ + +input[type="range"]::-ms-thumb { + appearance: none; + // box-shadow: 0 0 10px rgba(black, .15); + border: none; + height: 14px; + width: 14px; + border-radius: 7px; + background: white; + cursor: pointer; +} + +input[type="range"]::-ms-fill-lower, +input[type="range"]::-ms-fill-upper, +input[type="range"]::-ms-tooltip { + display: none; +} + +input[type="color"] { + appearance: none; + -moz-appearance: none; + -webkit-appearance: none; + background: none; + border: 0; + cursor: pointer; + height: 22px; + padding: 0; + width: 20px; + border-radius: 20px; +} \ No newline at end of file diff --git a/frontend/src/assets/styles/components/sideBar/_object.scss b/frontend/src/assets/styles/components/sideBar/_object.scss new file mode 100644 index 0000000..3d7a576 --- /dev/null +++ b/frontend/src/assets/styles/components/sideBar/_object.scss @@ -0,0 +1,174 @@ +.object-wrapper { + width: 100%; + // padding-top: 8px; + flex-direction: column; + gap: 10px; + + .sub-header { + width: 100%; + } + + + .objectInput-wrapper, + .checkBox, + .editData { + border-bottom: 1px solid var(--border-color-20); + } + + .head { + font-size: var(--font-size-title); + color: var(--lite-gray-80); + } + + + + + + + .userDatas { + width: 100%; + // padding-bottom: 15px; + + .sub-header { + padding-bottom: 16px; + + .add { + cursor: pointer; + user-select: none; + } + } + + .data-wrapper { + flex-direction: column; + width: 100%; + gap: 10px; + + .data { + width: 100%; + } + + .left { + gap: 10px; + + input { + width: 110px; + height: 18px; + border: 1px solid var(--highlight-light-color); + } + + .close-button { + cursor: pointer; + } + } + } + } + + .editData { + width: 100%; + border: 1px solid var(--highlight-light-color); + border-radius: 6px; + padding: 10px; + + .sub-header { + padding-bottom: 10px; + } + + .editData-wrapper { + flex-direction: column; + align-items: start; + gap: 10px; + .edit-data-list { + width: 100%; + } + + .minMax { + gap: 6px; + input { + width: 58px; + } + } + table { + width: 100%; + border-spacing: 0 10px; + } + + .key { + text-align: left; + padding: 0 8px; + } + + input.full-width { + width: 100px; + box-sizing: border-box; + } + + input.max-width { + width: 58px; + } + } + + .btn-container { + display: flex; + justify-content: flex-end; + width: 100%; + gap: 20px; + padding-top: 20px; + + button { + padding: 5px 19px; + } + .cancel { + background-color: var(--button-abort-color); + color: var(--primary-color); + } + } + } +} + + +// Position,Scale,Rotation style + + +.checkBox, +.objectInput-wrapper { + padding-top: 0px; + padding-bottom: 15px; + // border-bottom: 1px solid var(--border-color); + display: flex; + flex-direction: column; + gap: 10px; + width: 100%; + gap: 15px; + + .objectInput-container { + display: flex; + flex-direction: column; + gap: 6px; + } + + .label { + width: 100%; + justify-content: space-between; + } + + .objectInputs { + display: flex; + align-items: center; + gap: 6px; + + .object-input { + + display: flex; + align-items: center; + gap: 6px; + + .value { + width: 36px; + + input { + width: 100%; + } + } + } + } +} \ No newline at end of file diff --git a/frontend/src/assets/styles/components/sideBar/_overView.scss b/frontend/src/assets/styles/components/sideBar/_overView.scss new file mode 100644 index 0000000..1fa4127 --- /dev/null +++ b/frontend/src/assets/styles/components/sideBar/_overView.scss @@ -0,0 +1,65 @@ +.overlay-layout { + width: 100%; + display: flex; + flex-direction: column; +} + +.layout { + width: 100%; + flex-direction: column; + + .layout-header { + width: 100%; + padding: 6px 0px; + display: flex; + justify-content: space-between; + cursor: pointer; + transition: background-color 0.2s ease; + + } + + .layout-header:hover { + background-color: #f0f0f0; + } + + + + .icons { + display: flex; + gap: 7.5px; + align-items: center; + } +} + +.items-container { + width: 100%; + padding: 5px 0; +} + +.items-wrapper { + display: flex; + justify-content: space-between; + padding: 4px 0px; + padding-left: 10px; + cursor: pointer; + transition: background-color 0.2s ease; +} + +.items-wrapper:hover { + background-color: #f9f9f9; +} + +.items-wrapper.selected { + background-color: #e0dfff; + + /* Selected item background */ + div { + color: #ffffff; + } +} + +.icons { + display: flex; + gap: 7.5px; + align-items: center; +} \ No newline at end of file diff --git a/frontend/src/assets/styles/components/sideBar/_widgets.scss b/frontend/src/assets/styles/components/sideBar/_widgets.scss new file mode 100644 index 0000000..2b46acf --- /dev/null +++ b/frontend/src/assets/styles/components/sideBar/_widgets.scss @@ -0,0 +1,24 @@ +.widgets-layout { + display: flex; + flex-direction: column; + gap: 12px; + width: 100%; + max-height: 100%; + overflow-y: auto; + // padding: 12px 0; + overflow: visible; + &::-webkit-scrollbar { + display: none; + } + + .chart { + width: 100%; + height: 160px; + border-radius: 8px; + background: #FFFFFF; + border: 1.23px solid #F7F7F7; + box-shadow: 0px 4.91px 4.91px 0px #0000001C; + flex-shrink: 0; + padding: 5px 0; + } +} \ No newline at end of file diff --git a/frontend/src/assets/styles/components/toogleSwitch/_toogleSwitch.scss b/frontend/src/assets/styles/components/toogleSwitch/_toogleSwitch.scss new file mode 100644 index 0000000..e41955c --- /dev/null +++ b/frontend/src/assets/styles/components/toogleSwitch/_toogleSwitch.scss @@ -0,0 +1,121 @@ +@use "../../abstracts/variables"; + +.content-container { + // height: calc(100vh - 73px); + height: 100%; + height: calc(100vh - 97px); +} + +.switches { + width: 100%; + height: 100%; + min-width: 250px; + position: relative; + flex-grow: 1; + .canvas{ + width: 100%; + height: 100%; + position: fixed; + top: 0; + left: 0; + } + .switch-tools { + position: absolute; + width: 100%; + gap: 16px; + padding: 16px; + pointer-events: none; + + .top { + gap: 16px; + } + + .upload { + height: 32px; + background-color: var(--primary-color); + position: relative; + padding: 4px 20px; + border-radius: 8px; + pointer-events: all; + + input[type="file"] { + display: none; + + span { + z-index: 1; + } + } + + .UploadIcon { + display: none; + } + + &:hover { + + span, + path { + fill: var(--secondary-color); + color: var(--secondary-color); + } + + box-shadow: variables.$shadow-main; + outline: 1px solid var(--secondary-color); + } + } + + .toggle-container { + display: flex; + justify-content: center; + align-items: center; + user-select: none; + + .toggle-switch { + width: 80px; + height: 30px; + box-shadow: var(--shadow-main); + border-radius: 10px; + position: relative; + cursor: pointer; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0; + transition: background-color 0.3s ease; + overflow: hidden; + pointer-events: all; + } + + .toggle-switch.am { + background-color: var(--primary-color); + } + + .toggle-switch.pm { + background-color: var(--primary-color); + } + + .am-label, + .pm-label { + color: var(--selected-text-gray); + font-size: 12px; + width: 50%; + text-align: center; + position: relative; + z-index: 2; + } + + .toggle-knob { + width: 50%; + height: 100%; + background-color: var(--secondary-color); + border-radius: 8px; + position: absolute; + transition: transform 0.3s ease; + z-index: 1; + } + + .toggle-switch.pm .toggle-knob { + transform: translateX(100%); + } + } + } +} \ No newline at end of file diff --git a/frontend/src/assets/styles/components/toolBar/_toolBar.scss b/frontend/src/assets/styles/components/toolBar/_toolBar.scss new file mode 100644 index 0000000..a0afc37 --- /dev/null +++ b/frontend/src/assets/styles/components/toolBar/_toolBar.scss @@ -0,0 +1,48 @@ +.toolbar-wrapper { + position: absolute; + top: 50%; + left: 255px; + transform: translate(0, -50%); + flex-direction: column; + padding-left: 16px; + pointer-events: none; + .tool-button { + position: relative; + pointer-events: all; + background-color: var(--primary-color); + border-radius: 8px; + height: 30px; + width: 30px; + box-shadow: var(--shadow-main); + cursor: pointer; + .tool-tip { + display: none; + position: absolute; + left: 40px; + white-space: nowrap; + background-color: var(--primary-color); + border-radius: 6px; + min-width: 70px; + text-align: center; + padding: 4px 0; + box-sizing: var(--shadow-main); + &::before { + content: ""; + background-color: var(--primary-color); + position: absolute; + height: 6px; + width: 6px; + left: -5px; + top: 50%; + transform: translate(0, -50%); + clip-path: path("M0 4L7 8V0L0 4Z"); + } + } + &:hover { + outline: 2px solid var(--secondary-color); + .tool-tip { + display: block; + } + } + } +} diff --git a/frontend/src/assets/styles/layout/_aside.scss b/frontend/src/assets/styles/layout/_aside.scss new file mode 100644 index 0000000..1cc0ca2 --- /dev/null +++ b/frontend/src/assets/styles/layout/_aside.scss @@ -0,0 +1,431 @@ +@use "../abstracts/variables"; + +.sideBar-wrapper, +.sideBar-layout2-wrapper { + width: 255px; + min-width: 255px; + height: 100%; + box-shadow: var(--shadow-main); + background-color: var(--primary-color); + padding: 12px; + gap: 6px; + flex-direction: column; + justify-content: flex-start; + padding-top: 3px; + position: relative; + z-index: 10; + + .header { + width: 100%; + justify-content: space-around; + border-bottom: 1px solid var(--border-color); + padding: 10px 0; + + .head { + padding: 4px; + width: 100%; + text-align: center; + cursor: pointer; + } + } + + .subHeader { + gap: 10px; + + .filter { + width: 30px; + } + } + + .searchHistory { + width: 100%; + height: 26px; + border: 1px solid var(--border-color-20); + border-radius: 6px; + position: relative; + + input { + width: 100%; + height: 100%; + padding-left: 6px; + padding-right: 30px; + border-radius: 6px; + + &::placeholder { + font-size: var(--font-size-small); + color: var(--border-color-20); + } + } + + .searchIcon { + position: absolute; + right: 6px; + top: 50%; + transform: translate(0, -50%); + } + } + + .groups-container { + width: 100%; + display: flex; + flex-direction: column; + gap: 10px; + padding-top: 10px; + user-select: none; + overflow: auto; + + &::-webkit-scrollbar { + display: none; + } + + .group-item { + display: flex; + flex-direction: column; + align-items: end; + gap: 10px; + } + + .group-header { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + cursor: pointer; + + .header-content { + display: flex; + align-items: center; + + .header-title { + color: variables.$lite-gray-80; + font-size: var(--font-size-default); + } + } + + .header-actions { + display: flex; + align-items: center; + gap: 6px; + } + } + + .children-container { + width: 90%; + flex-direction: column; + justify-content: space-between; + gap: 10px; + } + + .child-item { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + gap: 6px; + + .icons { + width: 14px; + } + + .child-content { + flex: 1; + } + + .child-actions { + display: flex; + align-items: center; + gap: 6px; + } + } + } + + .assets-container { + flex-wrap: wrap; + padding: 10px 5px; + padding-right: 1px; + gap: 15px; + overflow: auto; + + &::-webkit-scrollbar { + width: 4px; + height: 0; + } + + /* Track */ + &::-webkit-scrollbar-track { + background: #f1f1f1; + } + + /* Handle */ + &::-webkit-scrollbar-thumb { + border-radius: 4px; + background: var(--secondary-color); + } + + /* Handle on hover */ + &::-webkit-scrollbar-thumb:hover { + background: #35579c; + } + + .asset-item { + width: 99.97px; + height: 100.6px; + border-radius: 5.06px; + box-shadow: var(--shadow-main); + flex-direction: column; + padding: 6px; + user-select: none; + + &:hover { + outline: 2px solid var(--secondary-color); + cursor: grab; + } + + img { + width: 79.62px; + height: 60.7px; + object-fit: cover; + } + + .head { + width: 100%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + } + } + + + .sideBar-header { + .regularDropdown-container { + width: 60px; + border: none; + outline: none; + + .dropdown-header { + border: none; + + } + } + } +} + +.sideBar-layout2-wrapper { + flex-direction: row-reverse; + min-width: 0px; + padding: 0; + align-items: flex-start; + + .side-flow-header { + height: 100%; + min-width: 32px; + width: 32px; + border-left: 2px solid var(--highlight-light-color); + + .sidebar-header-list { + height: 32px; + width: 32px; + cursor: pointer; + } + + .selected { + border-radius: 2px 0 0 2px; + outline: 1px solid var(--secondary-color); + cursor: default; + + &:hover { + outline: 1px solid var(--secondary-color); + } + } + } + + .object-wrapper { + padding: 8px; + width: calc(100% - 44px); + } + + .world-settings-wrapper { + position: relative; + height: 100%; + width: 100%; + padding: 8px; + + .world-settings-container { + height: 100%; + width: 100%; + + .split-h { + height: 2px; + width: 100%; + background-color: var(--highlight-light-color); + margin: 8px 0; + } + + .world-setting-content-container { + .input-container { + margin: 8px 0; + + .input-label { + min-width: 60px; + max-width: 120px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + + input[type="checkbox"] { + margin-right: 12px; + } + + input[type="button"] { + cursor: pointer; + min-width: 100px; + + &:hover { + outline: 1px solid var(--secondary-color); + } + + &:active, + &:focus { + outline: 1px solid var(--lite-gray-40); + } + } + + input[type="number"] { + width: 38px; + border: none; + outline: none; + + &:active, + &:focus { + outline: 1px solid var(--secondary-color); + } + } + } + } + } + } +} + +.canvas-tools-wrapper { + display: flex; + justify-content: center; + align-items: center; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, 50%); +} + +.canvas-tools { + display: flex; + flex-wrap: wrap; + justify-content: center; + align-items: center; + position: relative; + width: 240px; + height: 240px; + overflow: hidden; + padding: 10px; +} + +.icons-wrapper { + position: absolute; + width: 32.94px; + height: 32.94px; + animation: rotateIcon 1s forwards; + box-shadow: var(--shadow-main); + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + transform: rotate(calc(var(--final-rotation) * 1deg)); + cursor: pointer; + + .icons { + transform: rotate(calc(var(--final-rotation) * 3)); + } +} + +@keyframes rotateIcon { + from { + transform: rotate(0) translateY(0); + } + + to { + transform: rotate(var(--final-rotation)) translateY(-100px); + } +} + +/* Adjust the following based on how many icons you have */ +.icons-wrapper:nth-child(1) { + --final-rotation: 90deg; +} + +.icons-wrapper:nth-child(2) { + --final-rotation: 60deg; +} + +.icons-wrapper:nth-child(3) { + --final-rotation: 30deg; +} + +.icons-wrapper:nth-child(4) { + --final-rotation: 0deg; +} + +.icons-wrapper:nth-child(5) { + --final-rotation: -30deg; +} + +.icons-wrapper:nth-child(6) { + --final-rotation: -60deg; +} + +.icons-wrapper:nth-child(7) { + --final-rotation: -90deg; +} + +.contextMenu { + width: 148px; + color: var(--primary-color); + box-shadow: var(--shadow-main); + padding: 8px 0px; + display: flex; + flex-direction: column; + gap: 4px; + border-radius: 10px; + position: absolute; + z-index: 10; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + + .context-menu-list { + justify-content: flex-start; + gap: 10px; + cursor: pointer; + padding: 0 12px; + height: 22px; + border-radius: 4px; + + &:hover { + color: var(--primary-color); + background-color: var(--secondary-color); + + .icons { + filter: invert(1); + } + } + + .icons { + scale: 0.75; + width: 20px; + display: flex; + justify-content: center; + align-items: center; + pointer-events: none; + } + } +} \ No newline at end of file diff --git a/frontend/src/assets/styles/layout/_footer.scss b/frontend/src/assets/styles/layout/_footer.scss new file mode 100644 index 0000000..180f30d --- /dev/null +++ b/frontend/src/assets/styles/layout/_footer.scss @@ -0,0 +1,215 @@ +.footer-wrapper { + width: 100%; + height: 24px; + // position: absolute; + // bottom: 0; + // right: 0; + // position: relative; + position: fixed; + bottom: 0; + z-index: 10; + justify-content: flex-start; + gap: 60px; + padding: 0 10px; + background-color: var(--primary-color); + border: none; + + // border-left: 1px solid var(--lite-gray-40); + // border-right: 1px solid var(--lite-gray-40); + // .content-container { + // gap: 10px; + // height: calc(100vh - 73px); + // } + + .footer-animation-wrapper { + // width: 237px; + height: 355px; + } + + .node-simulation-wrapper { + width: 237px; + height: 100%; + // box-shadow: 5px 0px 9.42px 0px #0000001C; + border-right: 1px solid #EDEDED; + padding: 10px 20px; + display: flex; + flex-direction: column; + gap: 10px; + + .footer-nav { + padding: 0 10px; + + .nav { + padding: 5px 15px; + cursor: pointer; + } + } + + .simulation-wrapper { + .simulation { + padding: 10px 0px; + border-top: 1px solid #F2F2F2; + + &:last-child { + border-bottom: 1px solid #F2F2F2; + } + + .icon-wrapper { + display: flex; + align-items: center; + gap: 10px; + } + } + } + + .filtered-assets { + display: flex; + flex-direction: column; + gap: 10px; + overflow: auto; + + &::-webkit-scrollbar { + display: none; + /* Hide scrollbar */ + } + + .filtered-assets-wrapper { + .asset-item { + p { + + color: var(--text-gray); + } + + .icon-wrapper { + width: 26px; + height: 26px; + border-radius: 6px; + background-color: #FFFFFF; + box-shadow: 0px 2px 10px 0px #0000001C; + display: flex; + justify-content: center; + align-items: center; + } + } + } + } + } + + + .NodeProperties { + width: 237px; + height: 100%; + box-shadow: 5px 0px 9.42px 0px #0000001C; + padding: 10px 20px; + display: flex; + flex-direction: column; + gap: 10px; + + border: 1px solid #EDEDED; + + .header {} + + .nodepropertiesWrapper, + .additionalPropertiesWrapper { + display: flex; + flex-direction: column; + gap: 10px; + + .property { + gap: 10px; + + .key, + .value { + + font-size: 11px; + color: var(--text-gray); + font-size: 500; + } + + input { + + font-size: 11px; + color: #5D5D5DB2; + width: 140px; + + text-align: center; + } + } + } + } + + .add-simulation { + height: 31px; + justify-content: flex-start; + gap: 0; + + .add { + width: 30px; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + text-align: center; + cursor: pointer; + font-size: 18px; + } + + .added-simulation-wrapper { + overflow: scroll; + gap: 10px; + + &::-webkit-scrollbar { + display: none; + /* Hide scrollbar */ + } + } + + .simulation { + width: 165.5px; + height: 100%; + font-size: 12px; + font-weight: 600; + gap: 10px; + + .name { + color: inherit; + } + } + } +} + +.subHeader { + gap: 10px; + + .filter { + width: 30px; + } +} + +.searchHistory { + width: 100%; + height: 26px; + border: 1px solid var(--border-color-20); + border-radius: 6px; + position: relative; + + input { + width: 100%; + height: 100%; + padding-left: 6px; + padding-right: 30px; + border-radius: 6px; + + &::placeholder { + font-size: var(--font-size-small); + color: var(--border-color-20); + } + } + + .searchIcon { + position: absolute; + right: 6px; + top: 50%; + transform: translate(0, -50%); + } +} \ No newline at end of file diff --git a/frontend/src/assets/styles/layout/_grid.scss b/frontend/src/assets/styles/layout/_grid.scss new file mode 100644 index 0000000..4589f84 --- /dev/null +++ b/frontend/src/assets/styles/layout/_grid.scss @@ -0,0 +1,11 @@ +@use "../abstracts/mixins"; + +.flex { + @include mixins.flex-center; + gap: 14px; +} +.flex-sb { + top: 0; + @include mixins.flex-space-between; + gap: 4px; +} diff --git a/frontend/src/assets/styles/layout/_header.scss b/frontend/src/assets/styles/layout/_header.scss new file mode 100644 index 0000000..9d9a536 --- /dev/null +++ b/frontend/src/assets/styles/layout/_header.scss @@ -0,0 +1,78 @@ +@use "../abstracts/variables"; + +.header-wrapper { + box-shadow: var(--shadow-main); + padding: 3px 20px; + padding-bottom: 0%; + position: relative; + background-color: var(--primary-color); + z-index: 49; + + .menu-wrapper { + .menu-header { + justify-content: start; + font-size: variables.$font-size-default; + gap: 8px; + .logo { + color: var(--secondary-color); + font-size: 20px; + } + } + + .menu-container { + display: flex; + flex-direction: row; + } + + .menu { + padding: 12px 8px; + position: relative; + cursor: pointer; + border-bottom: 1px solid transparent; + + &:first-child { + padding-left: 5px; + } + } + + .active { + border-bottom: 1px solid variables.$secondary-color; + } + } + + .project-wrapper { + .project-name { + font-size: variables.$font-size-title; + } + } + + .organization-wrapper { + gap: 16px; + + .user-images { + gap: 0; + + .images, + .more-users { + display: flex; + align-items: center; + justify-content: center; + width: 28.37px; + height: 28.37px; + border-radius: 50%; + border: 1px solid variables.$selected-text-gray; + } + } + + .organization { + gap: 8px; + + img { + width: 24px; + height: 24px; + border-radius: 50%; + border: 1px solid #828282; + } + } + } +} diff --git a/frontend/src/assets/styles/main.scss b/frontend/src/assets/styles/main.scss new file mode 100644 index 0000000..94b753b --- /dev/null +++ b/frontend/src/assets/styles/main.scss @@ -0,0 +1,38 @@ +// abstracts +@use 'abstracts/variables'; +@use 'abstracts/mixins'; +@use 'abstracts/placeholders'; +@use 'abstracts/functions'; + +// base +@use 'base/reset'; +@use 'base/typography'; +@use 'base/base'; + +// components +@use 'components/inputs/button'; +@use 'components/inputs/dropDown'; +@use 'components/inputs/inputs'; +@use 'components/inputs/popup'; +@use 'components/card'; +@use 'components/toogleSwitch/toogleSwitch'; +@use 'components/undoRedo'; +@use 'components/toolBar/toolBar'; +@use 'components/sideBar/object'; +@use 'components/sideBar/material'; +@use 'components/sideBar/basic'; +@use 'components/sideBar/basicGlobal'; +@use 'components/sideBar/overView'; +@use 'components/sideBar/widgets'; +@use 'components/sideBar/data'; + +// layout +@use 'layout/grid'; +@use 'layout/header'; +@use 'layout/aside'; +@use 'layout/footer'; + +// pages +@use 'pages/home'; +@use 'pages/signIn'; +@use 'pages/realTimeViz'; \ No newline at end of file diff --git a/frontend/src/assets/styles/pages/_home.scss b/frontend/src/assets/styles/pages/_home.scss new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/assets/styles/pages/_realTimeViz.scss b/frontend/src/assets/styles/pages/_realTimeViz.scss new file mode 100644 index 0000000..6e7f17c --- /dev/null +++ b/frontend/src/assets/styles/pages/_realTimeViz.scss @@ -0,0 +1,436 @@ +// RealTimeVisualization.module.scss +@use "../abstracts/variables" as var; + +.realTime-viz { + .icon { + &:hover { + background-color: transparent; + // color: white; + fill: none; + } + } + + .content-container { + display: flex; + height: 100vh; + } + + .sideBar-header, + .search-main-container { + width: 100%; + } + + .chart-container { + display: flex; + flex-direction: column; + gap: 12px; + overflow-y: auto; + padding-bottom: 40px; + + &::-webkit-scrollbar { + display: none; + } + } + + .main-container { + position: relative; + flex: 1; + height: 600px; + background-color: rgb(235, 235, 235); + margin: 0 30px; + } + + // + button + // .side-button { + // position: absolute; + // cursor: pointer; + // transition: 0.3s; + // padding: 6px 11px; + + // &:hover { + // background: #4a90e2; + // color: white; + // } + + // &.top { + // top: -35px; + // left: 50%; + // transform: translateX(-50%); + // } + + // &.right { + // right: -35px; + // top: 50%; + // transform: translateY(-50%); + // } + + // &.bottom { + // bottom: -35px; + // left: 50%; + // transform: translateX(-50%); + // } + + // &.left { + // left: -35px; + // top: 50%; + // transform: translateY(-50%); + // } + // } + + .panel { + position: absolute; + background: white; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); + transition: all 0.3s ease; + border-radius: 6px; + overflow: visible !important; + + .panel-content { + overflow: visible !important; + + } + + &.top-panel { + top: 0; + left: 0; + right: 0; + + .panel-content { + display: flex; + + .chart-container { + height: 100%; + width: 230px; + // margin-right: 10px; + + } + } + } + + &.bottom-panel { + bottom: 0; + left: 0; + right: 0; + + .panel-content { + display: flex; + + .chart-container { + height: 100%; + width: 200px; + margin-right: 10px; + } + } + } + + &.left-panel { + left: 0; + top: 0; + bottom: 0; + + .chart-container { + width: 100%; + height: 200px; + } + } + + &.right-panel { + right: 0; + top: 0; + bottom: 0; + } + + + + .panel-content { + position: relative; + height: 100%; + padding: 10px; + overflow: auto; + display: flex; + flex-direction: column; + gap: 10px; + + &::-webkit-scrollbar { + display: none; + } + + .chart-container { + width: 100%; + height: 200px; + max-height: 100%; + border: 1px dotted #a9a9a9; + border-radius: 8px; + box-shadow: 0px 2px 6px 0px #3C3C431A; + padding: 0; + background-color: white; + padding: 6px 0; + } + + .close-btn { + position: absolute; + top: 5px; + right: 5px; + background: none; + border: none; + cursor: pointer; + color: #4a90e2; + } + } + } + + .search-main-container { + padding-bottom: 6px; + padding-top: 3px; + display: flex; + flex-direction: column; + gap: 8px; + border-bottom: 1px solid var(--border-color); + + .search-container { + .search-wrapper { + position: relative; + display: flex; + align-items: center; + + input { + width: 100%; + padding: 3px 4px; + padding-left: 26px; + + &:focus { + border-color: #8257e5; + box-shadow: 0 0 5px rgba(130, 87, 229, 0.3); + } + } + + .icon { + position: absolute; + top: 0%; + left: 12px; + transform: translate(-50%, 0%); + } + } + } + + .ui-wrapper { + position: relative; + display: flex; + justify-content: space-between; + align-items: center; + + .options { + display: flex; + gap: 12px; + + .option { + padding: 5px 10px; + border-radius: 8px; + cursor: pointer; + transition: background 0.3s, color 0.3s; + color: #555; + + &.active { + background-color: #5c87df; + color: hsl(0, 0%, 100%) !important; + } + } + } + + .theme-switch { + .theme-button { + width: 45px; + height: 25px; + border: none; + border-radius: 50px; + display: flex; + align-items: center; + justify-content: center; + gap: 4px; + cursor: pointer; + background-color: transparent; + box-shadow: none; + border: 1.23px solid var(--Grays-Gray-5, #e5e5ea); + color: hsl(0, 0%, 100%) !important; + padding: 0; + } + } + } + + } +} + +.top-panel, +.bottom-panel { + .panel-content { + display: flex; + flex-direction: row !important; + } + + .chart-container { + height: 100%; + width: 230px; + // margin-right: 10px; + } +} + +// drag and drop DraggableWidget in side-panel + + + +.theme-container { + width: 250px; + padding: 12px; + box-shadow: 1px -3px 4px 0px #0000001C; + border-radius: 8px; + background-color: #fff; + position: absolute; + top: 20px; + right: -100%; + transform: translate(-0%, 0); + + .theme-preset-wrapper { + display: flex; + gap: 5px; + flex-wrap: wrap; + + .theme-preset { + display: flex; + gap: 2px; + margin-bottom: 10px; + border: 1px solid #E0DFFF; + padding: 5px 10px; + border-radius: 4px; + + .color { + width: 15px; + height: 15px; + border-radius: 50%; + } + } + + .active { + border: 1px solid #6F42C1; + position: relative; + + &::after { + content: ''; + position: absolute; + top: 1px; + left: 1px; + width: 10px; + height: 10px; + background-color: #6F42C1; + border-radius: 50%; + } + } + } + + .custom-color { + display: flex; + justify-content: space-between; + + .color-displayer { + display: flex; + gap: 5px; + align-items: center; + border: 1px solid #E0DFFF; + border-radius: 4px; + padding: 0px 5px; + + input { + border: none; + outline: none; + border-radius: 50%; + } + } + } +} + +.theme-container h2 { + font-size: 12px; + margin-bottom: 8px; + color: #2B3344; + +} + + + + + + + +.side-button-container { + position: absolute; + display: flex; + flex-direction: column; + align-items: center; + background-color: #FCFDFD; + padding: 5px; + border-radius: 4px; +} + +.side-button { + + // position: absolute; + cursor: pointer; + transition: 0.3s; + padding: 6px 11px; +} + +.side-button:hover { + background-color: #4a90e2; + color: white; +} + +.extra-buttons { + display: none; + flex-direction: column; + gap: 5px; + align-items: center; +} + +.icon { + // width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; +} + +.top.side-button-container { + top: -42px; + left: 50%; + transform: translateX(-50%); + flex-direction: row; + + .extra-buttons { + display: flex; + flex-direction: row; + } + +} + +.right.side-button-container { + right: -42px; + top: 50%; + transform: translateY(-50%); +} + +.bottom.side-button-container { + bottom: -42px; + left: 50%; + transform: translateX(-50%); + flex-direction: row; + + .extra-buttons { + display: flex; + flex-direction: row; + } +} + +.left.side-button-container { + left: -42px; + top: 50%; + transform: translateY(-50%); +} \ No newline at end of file diff --git a/frontend/src/assets/styles/pages/_signIn.scss b/frontend/src/assets/styles/pages/_signIn.scss new file mode 100644 index 0000000..a886ac0 --- /dev/null +++ b/frontend/src/assets/styles/pages/_signIn.scss @@ -0,0 +1,115 @@ +.sign-in-sign-up-wrapper { + height: 100vh; + width: 100vw; + .sign-in-sign-up-container { + position: relative; + height: 100%; + width: 100%; + background-color: #edf1f7; + padding: 60px; + .cover-page-container { + position: absolute; + left: 60px; + padding: 24px; + transition: left 1s; + max-width: 40vw; + .text { + width: 100%; + font-size: 3.5vw; + font-weight: 600; + color: #181818; + } + .span { + color: #434343; + padding: 32px 0; + text-align: justify; + font-size: 14px; + font-weight: 200; + } + img { + position: relative; + width: 100%; + left: 120px; + bottom: -120px; + transition: left 0.5s; + scale: 1.4; + // filter: drop-shadow(0px 12px 6px #00000027); + } + } + .content-container { + position: absolute; + right: 60px; + height: calc(100% - 120px); + width: 40vw; + background: var(--primary-color); + border-radius: 32px; + padding: 42px; + transition: right 1s; + box-shadow: 2px 2px 40px #e5e9ee; + .header { + font-size: 24px; + font-weight: 600; + color: var(--selected-text-gray); + margin: 18px 8px; + } + .form-container { + padding: 32px 0; + form { + .input-container { + margin: 16px; + width: calc(100% - 32px); + .label { + color: var(--selected-text-gray); + } + input { + width: 100%; + padding: 12px 24px; + border-radius: 16px; + margin: 12px 0; + } + input[type="submit"] { + background-color: var(--secondary-color); + color: var(--primary-color); + border: none; + outline: none; + cursor: pointer; + transition: all 0.2s; + &:hover { + transform: translate(0, -2px); + box-shadow: var(--shadow-main); + } + } + } + .forgetpassword { + } + } + } + .footer-container { + padding: 24px; + .switch-sign-in-sign-up { + display: flex; + gap: 6px; + .content { + font-size: 14px; + } + .switch-button { + font-size: 14px; + color: var(--secondary-color); + cursor: pointer; + } + } + } + } + } + .switch { + .cover-page-container { + left: calc(100% - (45vw + 60px)); + img { + left: -60px; + } + } + .content-container { + right: calc(100% - (40vw + 60px)); + } + } +} diff --git a/frontend/src/assets/textures/floor/concreteFloorWorn001Diff2k.jpg b/frontend/src/assets/textures/floor/concreteFloorWorn001Diff2k.jpg new file mode 100644 index 0000000..f8ffbd3 Binary files /dev/null and b/frontend/src/assets/textures/floor/concreteFloorWorn001Diff2k.jpg differ diff --git a/frontend/src/assets/textures/floor/concreteFloorWorn001NorGl2k.jpg b/frontend/src/assets/textures/floor/concreteFloorWorn001NorGl2k.jpg new file mode 100644 index 0000000..896b67f Binary files /dev/null and b/frontend/src/assets/textures/floor/concreteFloorWorn001NorGl2k.jpg differ diff --git a/frontend/src/assets/textures/floor/largeFloorTiles02Diff4k.jpg b/frontend/src/assets/textures/floor/largeFloorTiles02Diff4k.jpg new file mode 100644 index 0000000..7c733fd Binary files /dev/null and b/frontend/src/assets/textures/floor/largeFloorTiles02Diff4k.jpg differ diff --git a/frontend/src/assets/textures/floor/largeFloorTiles02Nor4k.jpg b/frontend/src/assets/textures/floor/largeFloorTiles02Nor4k.jpg new file mode 100644 index 0000000..3406bbb Binary files /dev/null and b/frontend/src/assets/textures/floor/largeFloorTiles02Nor4k.jpg differ diff --git a/frontend/src/assets/textures/hdr/mudroadpuresky2k.hdr b/frontend/src/assets/textures/hdr/mudroadpuresky2k.hdr new file mode 100644 index 0000000..0a03764 Binary files /dev/null and b/frontend/src/assets/textures/hdr/mudroadpuresky2k.hdr differ diff --git a/frontend/src/components/3d-ui/distanceText.jsx b/frontend/src/components/3d-ui/distanceText.jsx new file mode 100644 index 0000000..ba1847e --- /dev/null +++ b/frontend/src/components/3d-ui/distanceText.jsx @@ -0,0 +1,89 @@ +import { useEffect, useState } from "react" +import { getLines } from "../../services/factoryBuilder/lines/getLinesApi"; +import * as THREE from "three"; +import { useActiveLayer, useDeletedLines, useNewLines, useToggleView } from "../../store/store"; +import objectLinesToArray from "../scene/geomentries/lines/lineConvertions/objectLinesToArray"; +import { Html } from "@react-three/drei"; + + +const DistanceText = () => { + const [lines, setLines] = useState([]); + const { activeLayer } = useActiveLayer(); + const { toggleView } = useToggleView(); + const { newLines, setNewLines } = useNewLines(); + const { deletedLines, setDeletedLines } = useDeletedLines(); + + useEffect(() => { + const email = localStorage.getItem('email') + const organization = (email.split("@")[1]).split(".")[0]; + + getLines(organization).then((data) => { + data = objectLinesToArray(data); + + const lines = data.filter(line => line[0][2] === activeLayer) + .map(line => { + const point1 = new THREE.Vector3(line[0][0].x, line[0][0].y, line[0][0].z); + const point2 = new THREE.Vector3(line[1][0].x, line[1][0].y, line[1][0].z); + const distance = point1.distanceTo(point2); + const midpoint = new THREE.Vector3().addVectors(point1, point2).divideScalar(2); + return { + distance: distance.toFixed(1), + position: midpoint, + userData: line, + layer: activeLayer, + }; + }); + setLines(lines) + }) + }, [activeLayer]) + + useEffect(() => { + if (newLines.length > 0) { + if (newLines[0][0][2] !== activeLayer ) return; + const newLinesData = newLines.map((line) => { + const point1 = new THREE.Vector3(line[0][0].x, line[0][0].y, line[0][0].z); + const point2 = new THREE.Vector3(line[1][0].x, line[1][0].y, line[1][0].z); + const distance = point1.distanceTo(point2); + const midpoint = new THREE.Vector3().addVectors(point1, point2).divideScalar(2); + + return { + distance: distance.toFixed(1), + position: midpoint, + userData: line, + layer: activeLayer, + }; + }); + setLines((prevLines) => [...prevLines, ...newLinesData]); + setNewLines([]); + } + }, [newLines, activeLayer]); + + + useEffect(() => { + if (deletedLines.length > 0) { + setLines((prevLines) => + prevLines.filter( + (line) => !deletedLines.some((deletedLine) => deletedLine[0][1] === line.userData[0][1] && deletedLine[1][1] === line.userData[1][1]) + ) + ); + setDeletedLines([]); + } + }, [deletedLines]); + + return ( + <> + {toggleView && ( + + {lines.map((text) => ( + +
{text.distance} m
+ + ))} +
+ )} + + ) + +} + +export default DistanceText; \ No newline at end of file diff --git a/frontend/src/components/3d-ui/functions/updateDistanceText.ts b/frontend/src/components/3d-ui/functions/updateDistanceText.ts new file mode 100644 index 0000000..d0f7ede --- /dev/null +++ b/frontend/src/components/3d-ui/functions/updateDistanceText.ts @@ -0,0 +1,42 @@ +import * as THREE from 'three'; + +import * as Types from "../../scene/world/worldTypes"; + +function updateDistanceText( + scene: THREE.Scene, + floorPlanGroupLine: Types.RefGroup, + affectedLines: Types.NumberArray +): void { + + ////////// Updating the Distance Texts of the lines that are affected during drag ////////// + + const DistanceGroup = scene.children.find((child) => child.name === "Distance_Text") as THREE.Group; + + affectedLines.forEach((lineIndex) => { + const mesh = floorPlanGroupLine.current.children[lineIndex] as THREE.Mesh; + const linePoints = mesh.userData.linePoints; + + if (linePoints) { + const distance = linePoints[0][0].distanceTo(linePoints[1][0]).toFixed(1); + const position = new THREE.Vector3().addVectors(linePoints[0][0], linePoints[1][0]).divideScalar(2); + + if (!DistanceGroup || !linePoints) { + return + } + + DistanceGroup.children.forEach((text) => { + const textMesh = text as THREE.Mesh; + if (textMesh.userData[0][1] === linePoints[0][1] && textMesh.userData[1][1] === linePoints[1][1]) { + textMesh.position.set(position.x, 1, position.z); + const className = `Distance line-${textMesh.userData[0][1]}_${textMesh.userData[1][1]}_${linePoints[0][2]}`; + const element = document.getElementsByClassName(className)[0] as HTMLElement; + if (element) { + element.innerHTML = `${distance} m`; + } + } + }); + } + }); +} + +export default updateDistanceText; diff --git a/frontend/src/components/3d-ui/referenceDistanceText.jsx b/frontend/src/components/3d-ui/referenceDistanceText.jsx new file mode 100644 index 0000000..3acfcce --- /dev/null +++ b/frontend/src/components/3d-ui/referenceDistanceText.jsx @@ -0,0 +1,39 @@ +import * as THREE from 'three'; +import { Html } from '@react-three/drei'; +import { useState, useEffect } from 'react'; +import { useActiveLayer } from '../../store/store'; + +const ReferenceDistanceText = ({ line }) => { + const [text, setTexts] = useState(null); + const { activeLayer } = useActiveLayer(); + + useEffect(() => { + if (line === undefined || line.parent === null) { + setTexts(null); + return; + } + const distance = line.userData.linePoints.cursorPosition.distanceTo(line.userData.linePoints.startPoint); + const midpoint = new THREE.Vector3().addVectors(line.userData.linePoints.cursorPosition, line.userData.linePoints.startPoint).divideScalar(2); + const newTexts = { + distance: distance.toFixed(1), + position: midpoint, + userData: line, + layer: activeLayer + }; + setTexts(newTexts); + }); + + return ( + + + {text !== null && + < Html transform sprite key={text.length} userData={text.userData} scale={5} position={[text.position.x, 1, text.position.z]} style={{ pointerEvents: 'none' }}> +
{text.distance} m
+ + } +
+
+ ); +}; + +export default ReferenceDistanceText; \ No newline at end of file diff --git a/frontend/src/components/layout/footer.tsx b/frontend/src/components/layout/footer.tsx new file mode 100644 index 0000000..d450ef2 --- /dev/null +++ b/frontend/src/components/layout/footer.tsx @@ -0,0 +1,27 @@ +import React from "react"; +import { + RightClickIcon, + LeftClickIcon, + CenterClickIcon, +} from "../../assets/images/svgExports"; + +const Footer = () => { + return ( +
+
+ +
Lorem ipsum
+
+
+ +
Lorem ipsum
+
+
+ +
Lorem ipsum
+
+
+ ); +}; + +export default Footer; diff --git a/frontend/src/components/layout/header.tsx b/frontend/src/components/layout/header.tsx new file mode 100644 index 0000000..2d1f297 --- /dev/null +++ b/frontend/src/components/layout/header.tsx @@ -0,0 +1,169 @@ +import React, { Key, useEffect, useState } from "react"; +import { + MenuBarIcon, + SettingsIcon, + SwitchAppIcon, +} from "../../assets/images/svgExports"; +import Renaming from "../ui/inputs/renaming"; +import CollabSettings from "../../pages/project/popUp/collabPopUp"; +import { useActiveUsers, useOrganization, useUserName } from "../../store/store"; +import fetchShareUsers from "../../services/factoryBuilder/collab/getUsersApi"; +import { useNavigate } from "react-router-dom"; + +interface HeaderProps { + activeMenu: string; + setActiveMenu: (menu: string) => void; +} + +const Header: React.FC = ({ activeMenu, setActiveMenu }) => { + const [users, setUsers] = useState([]); + let navigate = useNavigate(); + const [displayedUsers, setDisplayedUsers] = useState([]); + const [remainingUsersCount, setRemainingUsersCount] = useState(); + const { userName, setUserName } = useUserName(); + const { organization, setOrganization } = useOrganization(); + const [popupCollab, setPopupCollab] = useState(false); + const { activeUsers, setActiveUsers } = useActiveUsers(); + + const menuItems = [ + "Factory builder", + "Process creator", + "Simulation", + "Realtime visualization", + ]; + + // const users = [ + // "user-1", + // "user-2", + // "user-3", + // "user-4", + // "user-5", + // "user-6", + // "user-7", + // "user-8", + // "user-9", + // "user-10", + // ]; + + const maxDisplay = 3; + + const item = { key: "Item 1", details: "Details 1" }; + + const handleChangeValue = ( + newValue: string, + index: number, + details: string + ) => { }; + + const toggleCollab = () => { + setPopupCollab(!popupCollab); + } + + // useEffect(() => { + // const email = localStorage.getItem('email'); + // if (email) { + // const organization = email!.split("@")[1].split(".")[0]; + // fetchShareUsers(organization) + // .then((e) => { + // if (e.message === "scene shared datas") { + // const data = e.data; + // setUsers(data + // .filter((user: any) => user.email !== email) + // .map((user: any) => user.userName) + // ); + // } + // }); + // } else { + // navigate("/"); + // } + // }, []); + + useEffect(() => { + const email = localStorage.getItem('email'); + if (email) { + const users = activeUsers.filter((user: any) => user.email !== email).map((user: any) => user.userName); + setUsers(users); + } else { + navigate("/"); + } + }, [activeUsers]) + + useEffect(() => { + const displayedUsers = users.slice(0, maxDisplay); + setDisplayedUsers(displayedUsers); + const count = users.length > maxDisplay ? users.length - maxDisplay : 0; + setRemainingUsersCount(count); + }, [users]); + + + return ( +
+
+
+ +
Dwinzo
+
+ +
+ {menuItems.map((item) => ( +
setActiveMenu(item)} + > + <> + { } + {item} + +
+ ))} +
+
+ +
+
+ +
+
+ +
+
+ {remainingUsersCount !== undefined && remainingUsersCount > 0 && ( +
+{remainingUsersCount}
+ )} + {displayedUsers.map((user: string, index: number) => ( +
+ {/* Replace with user image component or element */} + {user.charAt(0).toUpperCase()} +
+ ))} +
+ +
Share
+ + {popupCollab && } + +
+ +
+
+ +
+ +
+
{organization}
+ {/* img */} +

{userName.charAt(0).toUpperCase()}

+
+
+
+ ); +}; + +export default Header; diff --git a/frontend/src/components/layout/sideBar.tsx b/frontend/src/components/layout/sideBar.tsx new file mode 100644 index 0000000..1ab0134 --- /dev/null +++ b/frontend/src/components/layout/sideBar.tsx @@ -0,0 +1,99 @@ +import React, { useState, useEffect } from "react"; +import asset1 from "../../assets/images/tempimages/asset1.png"; +import asset2 from "../../assets/images/tempimages/asset2.png"; +import asset3 from "../../assets/images/tempimages/asset3.png"; +import asset4 from "../../assets/images/tempimages/asset4.png"; +import asset5 from "../../assets/images/tempimages/asset5.png"; +import asset6 from "../../assets/images/tempimages/asset6.png"; +import asset7 from "../../assets/images/tempimages/asset7.png"; +import asset8 from "../../assets/images/tempimages/asset8.png"; +import asset9 from "../../assets/images/tempimages/asset9.png"; +import AssetsLists from "../ui/sideBar/assets"; +import Outline from "../ui/sideBar/outline"; +import Object from "../ui/sideBar/object"; +import Advanced from "../ui/sideBar/process creator/advanced"; +import Basic from "../ui/sideBar/process creator/basic"; +import Material from "../ui/sideBar/factory builder/material"; + +import AssetLibrary from "../ui/sideBar/assetLibrary"; +import Overview from "../ui/sideBar/realTimeViz/overview"; +import Widgets from "../ui/sideBar/realTimeViz/widgets"; +import Data from "../ui/sideBar/realTimeViz/data"; +import Design from "../ui/sideBar/realTimeViz/design"; + +interface FilteredAssets { + filename: string; + thumbnail: string; + modelfileID: string; +} + +interface SideBarProps { + header: string[]; + defaultActive?: string; // Optional prop to set default active header +} + +const SideBar: React.FC = ({ header, defaultActive }) => { + const [active, setActive] = useState( + defaultActive || header[0] || "" + ); + const [filteredData, setFilteredData] = useState([]); + const [inputData, setInputData] = useState(""); + + const [assets, setAssets] = useState([]); + + // const assets: FilteredAssets[] = [ + // { name: "Asset 1", img: asset1 }, + // { name: "Asset 2", img: asset2 }, + // { name: "Asset 3", img: asset3 }, + // { name: "Asset 4", img: asset4 }, + // { name: "Asset 5", img: asset5 }, + // { name: "Asset 6", img: asset6 }, + // { name: "Asset 7", img: asset7 }, + // { name: "Asset 8", img: asset8 }, + // { name: "Asset 9", img: asset9 }, + // ]; + + const handleInputChange = (event: React.ChangeEvent) => { + const value = event.target.value; + setInputData(value); + + const filtered = assets.filter((asset) => + asset.filename.toLowerCase().includes(value.toLowerCase()) + ); + setFilteredData(filtered); + }; + + useEffect(() => { + setActive(defaultActive || header[0]); + }, [header, defaultActive]); + + return ( +
+
+ {header.map((head, index) => ( +
{ + setActive(head); + }} + > + {head} +
+ ))} +
+ + {active === "Outline" && } + {active === "Asset library" && } + {active === "Overview" && } + {active === "Widgets" && } + {active === "Data" && } + {active === "Design" && } +
+ ); +}; + +export default SideBar; diff --git a/frontend/src/components/layout/sideBarLayout2.tsx b/frontend/src/components/layout/sideBarLayout2.tsx new file mode 100644 index 0000000..03bacb2 --- /dev/null +++ b/frontend/src/components/layout/sideBarLayout2.tsx @@ -0,0 +1,54 @@ +import React, { useEffect, useState } from "react"; +import Object from "../ui/sideBar/object"; +import { MaterialIcon, ObjectIcon, WorldIcon } from "../../assets/images/svgExports"; +import Material from "../ui/sideBar/factory builder/material"; +import WorldSettings from "../ui/sideBar/global/worldSettings"; +import Basic from "../ui/sideBar/process creator/basic"; +import Advanced from "../ui/sideBar/process creator/advanced"; + +interface SideBarLFProps { + header: string[]; + defaultActive?: string; +} + +const SideBarLF: React.FC = ({ header, defaultActive = "" }) => { + const [active, setActive] = useState(defaultActive); + + useEffect(() => { + setActive(defaultActive); + }, [defaultActive]); + + const toggleActive = (item: string) => { + setActive(prev => (prev !== item ? item : "")); + }; + + return ( +
+
+ {[header[0], header[1], "World"].map((item, index) => { + const Icon = [ObjectIcon, MaterialIcon, WorldIcon][index]; + return ( +
toggleActive(item)} + > + +
+ ); + })} +
+ + {active === "Object" && } + {active === "Material" && } + {active === "Basic" && } + {active === "Advanced" && } + {active === "World" && } + + ); +}; + +export default SideBarLF; \ No newline at end of file diff --git a/frontend/src/components/scene/IntialLoad/loadInitialFloorItems.ts b/frontend/src/components/scene/IntialLoad/loadInitialFloorItems.ts new file mode 100644 index 0000000..cb65d4b --- /dev/null +++ b/frontend/src/components/scene/IntialLoad/loadInitialFloorItems.ts @@ -0,0 +1,202 @@ +import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; +import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'; +import gsap from 'gsap'; +import * as THREE from 'three'; +import * as CONSTANTS from '../world/worldConstants'; +import { toast } from 'react-toastify'; +import * as Types from "../world/worldTypes"; +import { getFloorItems } from '../../../services/factoryBuilder/assest/floorAsset/getFloorItemsApi'; +import { initializeDB, retrieveGLTF, storeGLTF } from '../indexDB/idbUtils'; +import { getCamera } from '../../../services/factoryBuilder/camera/getCameraApi'; + +async function loadInitialFloorItems( + itemsGroup: Types.RefGroup, + setFloorItems: Types.setFloorItemSetState +): Promise { + if (!itemsGroup.current) return; + let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`; + const email = localStorage.getItem('email'); + const organization = (email!.split("@")[1]).split(".")[0]; + + const items = await getFloorItems(organization); + localStorage.setItem("FloorItems", JSON.stringify(items)); + await initializeDB(); + + if (items) { + const storedFloorItems: Types.FloorItems = items; + const loader = new GLTFLoader(); + const dracoLoader = new DRACOLoader(); + + dracoLoader.setDecoderPath('https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/'); + loader.setDRACOLoader(dracoLoader); + + let modelsLoaded = 0; + const modelsToLoad = storedFloorItems.length; + + const camData = await getCamera(organization, localStorage.getItem('userId')!); + let storedPosition; + if (camData && camData.position) { + storedPosition = camData?.position; + } else { + storedPosition = new THREE.Vector3(0, 40, 30); + } + if (!storedPosition) return; + const cameraPosition = new THREE.Vector3(storedPosition.x, storedPosition.y, storedPosition.z); + + storedFloorItems.sort((a, b) => { + const aPosition = new THREE.Vector3(a.position[0], a.position[1], a.position[2]); + const bPosition = new THREE.Vector3(b.position[0], b.position[1], b.position[2]); + return cameraPosition.distanceTo(aPosition) - cameraPosition.distanceTo(bPosition); + }); + + for (const item of storedFloorItems) { + if (!item.modelfileID) return; + const itemPosition = new THREE.Vector3(item.position[0], item.position[1], item.position[2]); + let storedPosition; + if (localStorage.getItem("cameraPosition")) { + storedPosition = JSON.parse(localStorage.getItem("cameraPosition")!); + } else { + storedPosition = new THREE.Vector3(0, 40, 30); + } + + const cameraPosition = new THREE.Vector3(storedPosition.x, storedPosition.y, storedPosition.z); + + if (cameraPosition.distanceTo(itemPosition) < 50) { + await new Promise(async (resolve) => { + + // Check Three.js Cache + const cachedModel = THREE.Cache.get(item.modelfileID!); + if (cachedModel) { + // console.log(`[Cache] Fetching ${item.modelname}`); + processLoadedModel(cachedModel.scene.clone(), item, itemsGroup, setFloorItems); + modelsLoaded++; + checkLoadingCompletion(modelsLoaded, modelsToLoad, dracoLoader, resolve); + return; + } + + // Check IndexedDB + const indexedDBModel = await retrieveGLTF(item.modelfileID!); + if (indexedDBModel) { + // console.log(`[IndexedDB] Fetching ${item.modelname}`); + const blobUrl = URL.createObjectURL(indexedDBModel); + loader.load( + blobUrl, + (gltf) => { + URL.revokeObjectURL(blobUrl); + THREE.Cache.remove(blobUrl); + THREE.Cache.add(item.modelfileID!, gltf); + processLoadedModel(gltf.scene.clone(), item, itemsGroup, setFloorItems); + modelsLoaded++; + checkLoadingCompletion(modelsLoaded, modelsToLoad, dracoLoader, resolve); + }, + undefined, + (error) => { + toast.error(`[IndexedDB] Error loading ${item.modelname}:`); + URL.revokeObjectURL(blobUrl); + resolve(); + } + ); + return; + } + + // Fetch from Backend + // console.log(`[Backend] Fetching ${item.modelname}`); + const modelUrl = `${url_Backend_dwinzo}/api/v1/AssetFile/${item.modelfileID!}`; + loader.load( + modelUrl, + async (gltf) => { + const modelBlob = await fetch(modelUrl).then((res) => res.blob()); + await storeGLTF(item.modelfileID!, modelBlob); + THREE.Cache.add(item.modelfileID!, gltf); + processLoadedModel(gltf.scene.clone(), item, itemsGroup, setFloorItems); + modelsLoaded++; + checkLoadingCompletion(modelsLoaded, modelsToLoad, dracoLoader, resolve); + }, + undefined, + (error) => { + toast.error(`[Backend] Error loading ${item.modelname}:`); + resolve(); + } + ); + }); + } else { + // console.log(`Item ${item.modelname} is not near`); + setFloorItems((prevItems) => [ + ...(prevItems || []), + { + modeluuid: item.modeluuid, + modelname: item.modelname, + position: item.position, + rotation: item.rotation, + modelfileID: item.modelfileID, + isLocked: item.isLocked, + isVisible: item.isVisible, + }, + ]); + modelsLoaded++; + checkLoadingCompletion(modelsLoaded, modelsToLoad, dracoLoader, () => { }); + } + } + + // Dispose loader after all models + dracoLoader.dispose(); + } +} + + +function processLoadedModel( + gltf: any, + item: Types.FloorItemType, + itemsGroup: Types.RefGroup, + setFloorItems: Types.setFloorItemSetState +) { + const model = gltf; + model.uuid = item.modeluuid; + model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap); + model.userData = { name: item.modelname, modelId: item.modelfileID }; + model.position.set(...item.position); + model.rotation.set(item.rotation.x, item.rotation.y, item.rotation.z); + + model.traverse((child: any) => { + if (child.isMesh) { + // Clone the material to ensure changes are independent + // child.material = child.material.clone(); + + child.castShadow = true; + child.receiveShadow = true; + } + }); + + + itemsGroup?.current?.add(model); + setFloorItems((prevItems) => [ + ...(prevItems || []), + { + modeluuid: item.modeluuid, + modelname: item.modelname, + position: item.position, + rotation: item.rotation, + modelfileID: item.modelfileID, + isLocked: item.isLocked, + isVisible: item.isVisible, + }, + ]); + + gsap.to(model.position, { y: item.position[1], duration: 1.5, ease: 'power2.out' }); + gsap.to(model.scale, { x: 1, y: 1, z: 1, duration: 1.5, ease: 'power2.out' }); +} + +function checkLoadingCompletion( + modelsLoaded: number, + modelsToLoad: number, + dracoLoader: DRACOLoader, + resolve: () => void +) { + if (modelsLoaded === modelsToLoad) { + toast.success("Models Loaded!"); + dracoLoader.dispose(); + } + resolve(); +} + +export default loadInitialFloorItems; \ No newline at end of file diff --git a/frontend/src/components/scene/IntialLoad/loadInitialLine.ts b/frontend/src/components/scene/IntialLoad/loadInitialLine.ts new file mode 100644 index 0000000..bedd24f --- /dev/null +++ b/frontend/src/components/scene/IntialLoad/loadInitialLine.ts @@ -0,0 +1,32 @@ +import addLineToScene from "../geomentries/lines/addLineToScene"; +import * as CONSTANTS from '../world/worldConstants'; +import * as Types from "../world/worldTypes"; + +function loadInitialLine( + floorPlanGroupLine: Types.RefGroup, + lines: Types.RefLines +): void { + + if (!floorPlanGroupLine.current) return + + ////////// Load the Lines initially if there are any ////////// + + floorPlanGroupLine.current.children = []; + lines.current.forEach((line) => { + let colour; + if (line[0][3] && line[1][3] === CONSTANTS.lineConfig.wallName) { + colour = CONSTANTS.lineConfig.wallColor; + } else if (line[0][3] && line[1][3] === CONSTANTS.lineConfig.floorName) { + colour = CONSTANTS.lineConfig.floorColor; + } else if (line[0][3] && line[1][3] === CONSTANTS.lineConfig.aisleName) { + colour = CONSTANTS.lineConfig.aisleColor; + } else if (line[0][3] && line[1][3] === CONSTANTS.lineConfig.zoneName) { + colour = CONSTANTS.lineConfig.zoneColor; + } + if (colour) { + addLineToScene(line[0][0], line[1][0], colour, line, floorPlanGroupLine); + } + }); +} + +export default loadInitialLine; diff --git a/frontend/src/components/scene/IntialLoad/loadInitialPoint.ts b/frontend/src/components/scene/IntialLoad/loadInitialPoint.ts new file mode 100644 index 0000000..0cb7886 --- /dev/null +++ b/frontend/src/components/scene/IntialLoad/loadInitialPoint.ts @@ -0,0 +1,88 @@ +import * as THREE from 'three'; + +import * as CONSTANTS from '../world/worldConstants'; +import * as Types from "../world/worldTypes"; + +////////// Load the Boxes initially if there are any ////////// + +function loadInitialPoint( + lines: Types.RefLines, + floorPlanGroupPoint: Types.RefGroup, + currentLayerPoint: Types.RefMeshArray, + dragPointControls: Types.RefDragControl +): void { + + if (!floorPlanGroupPoint.current) return + + floorPlanGroupPoint.current.children = []; + currentLayerPoint.current = []; + lines.current.forEach((line) => { + const colour = getPointColor(line[0][3]); + line.forEach((pointData) => { + const [point, id] = pointData; + + /////////// Check if a box with this id already exists ////////// + + const existingBox = floorPlanGroupPoint.current?.getObjectByProperty('uuid', id); + if (existingBox) { + return; + } + + const geometry = new THREE.BoxGeometry(...CONSTANTS.pointConfig.boxScale); + const material = new THREE.ShaderMaterial({ + uniforms: { + uColor: { value: new THREE.Color(colour) }, // Blue color for the border + uInnerColor: { value: new THREE.Color(CONSTANTS.pointConfig.defaultInnerColor) }, // White color for the inner square + }, + vertexShader: ` + varying vec2 vUv; + + void main() { + vUv = uv; + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); + } + `, + fragmentShader: ` + varying vec2 vUv; + uniform vec3 uColor; + uniform vec3 uInnerColor; + + void main() { + // Define the size of the white square as a proportion of the face + float borderThickness = 0.2; // Adjust this value for border thickness + if (vUv.x > borderThickness && vUv.x < 1.0 - borderThickness && + vUv.y > borderThickness && vUv.y < 1.0 - borderThickness) { + gl_FragColor = vec4(uInnerColor, 1.0); // White inner square + } else { + gl_FragColor = vec4(uColor, 1.0); // Blue border + } + } + `, + }); + const box = new THREE.Mesh(geometry, material); + box.name = "point"; + box.uuid = id; + box.userData = { type: line[0][3], color: colour }; + box.position.set(point.x, point.y, point.z); + currentLayerPoint.current.push(box); + + floorPlanGroupPoint.current?.add(box); + }); + }); + + function getPointColor(lineType: string | undefined): string { + switch (lineType) { + case CONSTANTS.lineConfig.wallName: return CONSTANTS.pointConfig.wallOuterColor; + case CONSTANTS.lineConfig.floorName: return CONSTANTS.pointConfig.floorOuterColor; + case CONSTANTS.lineConfig.aisleName: return CONSTANTS.pointConfig.aisleOuterColor; + case CONSTANTS.lineConfig.zoneName: return CONSTANTS.pointConfig.zoneOuterColor; + default: return CONSTANTS.pointConfig.defaultOuterColor; + } + } + + if (dragPointControls.current) { + dragPointControls.current!.objects = currentLayerPoint.current; + } +} + +export default loadInitialPoint; diff --git a/frontend/src/components/scene/IntialLoad/loadInitialWallItems.ts b/frontend/src/components/scene/IntialLoad/loadInitialWallItems.ts new file mode 100644 index 0000000..26c0eb7 --- /dev/null +++ b/frontend/src/components/scene/IntialLoad/loadInitialWallItems.ts @@ -0,0 +1,53 @@ +import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; + +import * as Types from "../world/worldTypes"; +import { getWallItems } from '../../../services/factoryBuilder/assest/wallAsset/getWallItemsApi'; + +////////// Load the Wall Items's intially of there is any ////////// + +async function loadInitialWallItems( + setWallItems: Types.setWallItemSetState, + AssetConfigurations: Types.AssetConfigurations +): Promise { + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + const items = await getWallItems(organization); + + localStorage.setItem("WallItems", JSON.stringify(items)); + if (items.length > 0) { + const storedWallItems: Types.wallItems = items; + + storedWallItems.forEach((item) => { + const loader = new GLTFLoader(); + loader.load(AssetConfigurations[item.modelname!].modelUrl, (gltf) => { + const model = gltf.scene; + model.uuid = item.modeluuid!; + + model.children[0].children.forEach((child: any) => { + if (child.name !== "CSG_REF") { + child.castShadow = true; + child.receiveShadow = true; + } + }); + + setWallItems((prevItems) => [ + ...prevItems, + { + type: item.type, + model: model, + modelname: item.modelname, + scale: item.scale, + csgscale: item.csgscale, + csgposition: item.csgposition, + position: item.position, + quaternion: item.quaternion, + }, + ]); + }); + }); + } +} + +export default loadInitialWallItems; diff --git a/frontend/src/components/scene/animation/animationSample.tsx b/frontend/src/components/scene/animation/animationSample.tsx new file mode 100644 index 0000000..b616a66 --- /dev/null +++ b/frontend/src/components/scene/animation/animationSample.tsx @@ -0,0 +1,94 @@ +import * as THREE from 'three'; +import { useState, useEffect, useRef, useMemo } from "react"; +import { useLoader, useFrame } from "@react-three/fiber"; +import { GLTFLoader } from "three-stdlib"; +import crate from "../../../assets/models/gltf-glb/crate_box.glb"; +import { useOrganization } from '../../../store/store'; + +export default function AnimationSample() { + const { organization } = useOrganization(); + const points = useMemo(() => [ + { position: new THREE.Vector3(0.2, 1.25, 0) }, + { position: new THREE.Vector3(15.95, 1.25, 0) }, + { position: new THREE.Vector3(15.95, 1.25, 15.7) }, + { position: new THREE.Vector3(0.2, 1.25, 15.7) }, + { position: new THREE.Vector3(0.2, 1.25, 9) }, + ], []); + + // const points = useMemo(() => [ + // { position: new Vector3(0, 1, 0) }, + // { position: new Vector3(5, 1, 0) }, + // { position: new Vector3(10, 1, 0) }, + // { position: new Vector3(15, 1, 0) }, + // { position: new Vector3(20, 1, 0) }, + // ], []); + + const spawnInterval = 1000; + const totalDuration = 20000; + + const [meshes, setMeshes] = useState<{ id: number }[]>([]); + const gltf = useLoader(GLTFLoader, crate); + + useEffect(() => { + if (organization !== 'hexrfactory') return; + let meshId = 0; + const interval = setInterval(() => { + setMeshes((prev) => [...prev, { id: meshId++ }]); + }, spawnInterval); + + return () => clearInterval(interval); + }, []); + + const removeMesh = (id: number) => { + setMeshes((prev) => prev.filter((m) => m.id !== id)); + }; + + return ( + <> + {meshes.map((mesh) => ( + + ))} + + ); +} + +function MovingMesh({ meshId, points, totalDuration, gltf, removeMesh }: any) { + const meshRef = useRef(); + const startTime = useRef(performance.now()); + const currentIndex = useRef(0); + const [position, setPosition] = useState(points[0].position.clone()); + + const distances = useMemo(() => { + return points.slice(1).map((point: any, i: number) => points[i].position.distanceTo(point.position)); + }, [points]); + + const totalDistance = useMemo(() => distances.reduce((sum: number, d: number) => sum + d, 0), [distances]); + + const timeIntervals = useMemo(() => distances.map((d: number) => (d / totalDistance) * totalDuration), [distances, totalDuration]); + + useFrame(() => { + if (!meshRef.current || points.length < 2) return; + + const elapsed = performance.now() - startTime.current; + + if (elapsed >= timeIntervals[currentIndex.current]) { + currentIndex.current += 1; + startTime.current = performance.now(); + } + + if (currentIndex.current >= points.length - 1) { + removeMesh(meshId); + return; + } + + const progress = (performance.now() - startTime.current) / timeIntervals[currentIndex.current]; + + meshRef.current.position.lerpVectors(points[currentIndex.current].position, points[currentIndex.current + 1].position, Math.min(progress, 1)); + }); + + return ( + + + + ); +} diff --git a/frontend/src/components/scene/camera/camMode.tsx b/frontend/src/components/scene/camera/camMode.tsx new file mode 100644 index 0000000..54c8371 --- /dev/null +++ b/frontend/src/components/scene/camera/camMode.tsx @@ -0,0 +1,89 @@ +import { useFrame, useThree } from '@react-three/fiber'; +import React, { useEffect, useState } from 'react'; +import * as CONSTANTS from '../world/worldConstants'; +import { useCamMode, useToggleView } from '../../../store/store'; +import { useKeyboardControls } from '@react-three/drei'; +import switchToThirdPerson from './switchToThirdPerson'; +import switchToFirstPerson from './switchToFirstPerson'; + +const CamMode: React.FC = () => { + const { camMode, setCamMode } = useCamMode(); + const [, get] = useKeyboardControls() + const [isTransitioning, setIsTransitioning] = useState(false); + const state: any = useThree(); + const { toggleView } = useToggleView(); + + useEffect(() => { + const handlePointerLockChange = async () => { + if (document.pointerLockElement && !toggleView) { + // console.log('Pointer is locked'); + } else { + // console.log('Pointer is unlocked'); + if (camMode === "FirstPerson" && !toggleView) { + setCamMode("ThirdPerson"); + await switchToThirdPerson(state.controls, state.camera); + } + } + }; + + document.addEventListener('pointerlockchange', handlePointerLockChange); + + return () => { + document.removeEventListener('pointerlockchange', handlePointerLockChange); + }; + }, [camMode, toggleView, setCamMode, state.controls, state.camera]); + + useEffect(() => { + const handleKeyPress = async (event: any) => { + if (!state.controls) return; + + if (event.key === "/" && !isTransitioning && !toggleView) { + setIsTransitioning(true); + state.controls.mouseButtons.left = CONSTANTS.controlsTransition.leftMouse; + state.controls.mouseButtons.right = CONSTANTS.controlsTransition.rightMouse; + state.controls.mouseButtons.wheel = CONSTANTS.controlsTransition.wheelMouse; + state.controls.mouseButtons.middle = CONSTANTS.controlsTransition.middleMouse; + + if (camMode === 'ThirdPerson') { + setCamMode("FirstPerson"); + await switchToFirstPerson(state.controls, state.camera); + } else if (camMode === "FirstPerson") { + setCamMode("ThirdPerson"); + await switchToThirdPerson(state.controls, state.camera); + } + + setIsTransitioning(false); + } + }; + + window.addEventListener("keydown", handleKeyPress); + return () => { + window.removeEventListener("keydown", handleKeyPress); + }; + }, [camMode, isTransitioning, toggleView, state.controls, state.camera, setCamMode]); + + useFrame(() => { + const { forward, backward, left, right } = get(); + if (!state.controls) return + if (!state.controls || camMode === "ThirdPerson" || !document.pointerLockElement) return; + + if (forward) { + state.controls.forward(CONSTANTS.firstPersonControls.forwardSpeed, true) + } + if (backward) { + state.controls.forward(CONSTANTS.firstPersonControls.backwardSpeed, true) + } + if (left) { + state.controls.truck(CONSTANTS.firstPersonControls.leftSpeed, 0, true) + } + if (right) { + state.controls.truck(CONSTANTS.firstPersonControls.rightSpeed, 0, true) + } + }); + + return ( + <> + ); +}; + +export default CamMode; \ No newline at end of file diff --git a/frontend/src/components/scene/camera/switchToFirstPerson.ts b/frontend/src/components/scene/camera/switchToFirstPerson.ts new file mode 100644 index 0000000..c76a33f --- /dev/null +++ b/frontend/src/components/scene/camera/switchToFirstPerson.ts @@ -0,0 +1,25 @@ +import * as THREE from 'three'; +import * as CONSTANTS from '../world/worldConstants'; + +export default async function switchToFirstPerson( + controls: any, + camera: any +) { + if (!controls) return; + + const cameraDirection = new THREE.Vector3(); + camera.getWorldDirection(cameraDirection); + cameraDirection.normalize(); + + await controls.setPosition(camera.position.x, 2, camera.position.z, true); + controls.setTarget(camera.position.x, 2, camera.position.z, true); + controls.mouseButtons.left = CONSTANTS.firstPersonControls.leftMouse; + controls.lockPointer(); + + controls.azimuthRotateSpeed = CONSTANTS.firstPersonControls.azimuthRotateSpeed; + controls.polarRotateSpeed = CONSTANTS.firstPersonControls.polarRotateSpeed; + controls.truckSpeed = CONSTANTS.firstPersonControls.truckSpeed; + controls.minDistance = CONSTANTS.firstPersonControls.minDistance; + controls.maxDistance = CONSTANTS.firstPersonControls.maxDistance; + controls.maxPolarAngle = CONSTANTS.firstPersonControls.maxPolarAngle; +} \ No newline at end of file diff --git a/frontend/src/components/scene/camera/switchToThirdPerson.ts b/frontend/src/components/scene/camera/switchToThirdPerson.ts new file mode 100644 index 0000000..d5acf2f --- /dev/null +++ b/frontend/src/components/scene/camera/switchToThirdPerson.ts @@ -0,0 +1,29 @@ +import * as THREE from 'three'; +import * as CONSTANTS from '../world/worldConstants'; + +export default async function switchToThirdPerson( + controls: any, + camera: any +) { + if (!controls) return; + controls.mouseButtons.left = CONSTANTS.thirdPersonControls.leftMouse; + controls.mouseButtons.right = CONSTANTS.thirdPersonControls.rightMouse; + controls.mouseButtons.middle = CONSTANTS.thirdPersonControls.middleMouse; + controls.mouseButtons.wheel = CONSTANTS.thirdPersonControls.wheelMouse; + controls.unlockPointer(); + + const cameraDirection = new THREE.Vector3(); + camera.getWorldDirection(cameraDirection); + const targetOffset = cameraDirection.multiplyScalar(CONSTANTS.thirdPersonControls.targetOffset); + const targetPosition = new THREE.Vector3(camera.position.x, camera.position.y, camera.position.z).add(targetOffset); + + controls.setPosition(camera.position.x, CONSTANTS.thirdPersonControls.cameraHeight, camera.position.z, true); + controls.setTarget(targetPosition.x, 0, targetPosition.z, true); + + controls.azimuthRotateSpeed = CONSTANTS.thirdPersonControls.azimuthRotateSpeed; + controls.polarRotateSpeed = CONSTANTS.thirdPersonControls.polarRotateSpeed; + controls.truckSpeed = CONSTANTS.thirdPersonControls.truckSpeed; + controls.minDistance = CONSTANTS.threeDimension.minDistance; + controls.maxDistance = CONSTANTS.thirdPersonControls.maxDistance; + controls.maxPolarAngle = CONSTANTS.thirdPersonControls.maxPolarAngle; +} \ No newline at end of file diff --git a/frontend/src/components/scene/camera/switchView.tsx b/frontend/src/components/scene/camera/switchView.tsx new file mode 100644 index 0000000..9611992 --- /dev/null +++ b/frontend/src/components/scene/camera/switchView.tsx @@ -0,0 +1,70 @@ +import * as THREE from "three"; +import { useEffect, useRef } from "react"; +import { useToggleView } from "../../../store/store"; +import { useThree } from "@react-three/fiber"; +import { getCamera } from "../../../services/factoryBuilder/camera/getCameraApi"; +import * as CONSTANTS from '../world/worldConstants'; + +export default function SwitchView() { + const { toggleView } = useToggleView(); + const state: any = useThree(); + const { set } = useThree(); + const perspectiveCamera = useRef(null); + const orthoCamera = useRef(null); + orthoCamera.current = new THREE.OrthographicCamera(-window.innerWidth / 2, window.innerWidth / 2, window.innerHeight / 2, -window.innerHeight / 2, 0.01, 1000); + perspectiveCamera.current = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 1000); + + useEffect(() => { + if (!perspectiveCamera.current || !orthoCamera.current) return; + if (toggleView) { + orthoCamera.current.zoom = 10; + orthoCamera.current.position.set(...CONSTANTS.twoDimension.defaultPosition); + orthoCamera.current.lookAt(new THREE.Vector3(...CONSTANTS.twoDimension.defaultTarget)); + orthoCamera.current.updateProjectionMatrix(); + set({ camera: orthoCamera.current }); + orthoCamera.current.updateProjectionMatrix(); + } else if (!toggleView) { + perspectiveCamera.current.position.set(...CONSTANTS.threeDimension.defaultPosition); + perspectiveCamera.current.lookAt(new THREE.Vector3(...CONSTANTS.threeDimension.defaultTarget)); + set({ camera: perspectiveCamera.current }); + } + }, [toggleView, set]); + + useEffect(() => { + if (toggleView && state.controls) { + state.controls.mouseButtons.left = CONSTANTS.twoDimension.leftMouse; + state.controls.mouseButtons.right = CONSTANTS.twoDimension.rightMouse; + } else { + try { + const email = localStorage.getItem('email'); + const organization = (email!.split("@")[1]).split(".")[0]; + getCamera(organization, localStorage.getItem('userId')!).then((data) => { + if (data && data.position && data.target) { + state.controls?.setPosition(data.position.x, data.position.y, data.position.z); + state.controls?.setTarget(data.target.x, data.target.y, data.target.z); + localStorage.setItem("cameraPosition", JSON.stringify(data.position)); + localStorage.setItem("controlTarget", JSON.stringify(data.target)); + } else { + state.controls?.setPosition(...CONSTANTS.threeDimension.defaultPosition); + state.controls?.setTarget(...CONSTANTS.threeDimension.defaultTarget); + localStorage.setItem("cameraPosition", JSON.stringify(new THREE.Vector3(...CONSTANTS.threeDimension.defaultPosition))); + localStorage.setItem("controlTarget", JSON.stringify(new THREE.Vector3(...CONSTANTS.threeDimension.defaultTarget))); + } + }); + } catch (error) { + console.error("Failed to retrieve camera position or target:", error); + state.controls?.setPosition(...CONSTANTS.threeDimension.defaultPosition); + state.controls?.setTarget(...CONSTANTS.threeDimension.defaultTarget); + } + + if (state.controls) { + state.controls.mouseButtons.left = CONSTANTS.threeDimension.leftMouse; + state.controls.mouseButtons.right = CONSTANTS.threeDimension.rightMouse; + } + } + }, [toggleView, state.controls]); + + return ( + <> + ); +} \ No newline at end of file diff --git a/frontend/src/components/scene/camera/updateCameraPosition.ts b/frontend/src/components/scene/camera/updateCameraPosition.ts new file mode 100644 index 0000000..4b76b1a --- /dev/null +++ b/frontend/src/components/scene/camera/updateCameraPosition.ts @@ -0,0 +1,26 @@ +import { Socket } from "socket.io-client"; +import * as THREE from 'three'; + +export default function updateCamPosition( + controls: any, + socket: Socket, + position: THREE.Vector3, + rotation: THREE.Euler +) { + if (!controls.current) return; + const target = controls.current.getTarget(new THREE.Vector3()); + const email = localStorage.getItem("email"); + const organization = email!.split("@")[1].split(".")[0]; + + const camData = { + organization: organization, + userId: localStorage.getItem("userId")!, + position: position, + target: new THREE.Vector3(target.x, 0, target.z), + rotation: new THREE.Vector3(rotation.x, rotation.y, rotation.z), + socketId: socket.id, + }; + socket.emit("v1:Camera:set", camData); + localStorage.setItem("cameraPosition", JSON.stringify(position)); + localStorage.setItem("controlTarget", JSON.stringify(new THREE.Vector3(target.x, 0, target.z))); +} \ No newline at end of file diff --git a/frontend/src/components/scene/collab/collabCams.tsx b/frontend/src/components/scene/collab/collabCams.tsx new file mode 100644 index 0000000..a42d49a --- /dev/null +++ b/frontend/src/components/scene/collab/collabCams.tsx @@ -0,0 +1,142 @@ +import * as THREE from 'three'; +import { useEffect, useRef, useState } from 'react'; +import { useFrame } from '@react-three/fiber'; +import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; +import camModel from '../../../assets/models/gltf-glb/camera face 2.gltf'; +import getActiveUsersData from '../../../services/factoryBuilder/collab/getActiveUsers'; +import { useActiveUsers, useSocketStore } from '../../../store/store'; +import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'; +import { useNavigate } from 'react-router-dom'; +import { Text, Html } from '@react-three/drei'; +import CollabUserIcon from './collabUserIcon'; +import image from '../../../assets/images/userImage.png' + + +const CamModelsGroup = () => { + let navigate = useNavigate(); + const groupRef = useRef(null); + const email = localStorage.getItem('email'); + const { activeUsers, setActiveUsers } = useActiveUsers(); + const { socket } = useSocketStore(); + const loader = new GLTFLoader(); + const dracoLoader = new DRACOLoader(); + const [cams, setCams] = useState([]); + const [models, setModels] = useState>({}); + + dracoLoader.setDecoderPath('three/examples/jsm/libs/draco/gltf/'); + loader.setDRACOLoader(dracoLoader); + + useEffect(() => { + if (!email) { + navigate('/'); + } + if (!socket) return; + const organization = email!.split('@')[1].split('.')[0]; + + socket.on('userConnectRespones', (data: any) => { + if (!groupRef.current) return; + if (data.data.userData.email === email) return + if (socket.id === data.socketId || organization !== data.organization) return; + + const model = groupRef.current.getObjectByProperty('uuid', data.data.userData._id); + if (model) { + groupRef.current.remove(model); + } + loader.load(camModel, (gltf) => { + const newModel = gltf.scene.clone(); + newModel.uuid = data.data.userData._id; + newModel.position.set(data.data.position.x, data.data.position.y, data.data.position.z); + newModel.rotation.set(data.data.rotation.x, data.data.rotation.y, data.data.rotation.z); + newModel.userData = data.data.userData; + setCams((prev) => [...prev, newModel]); + setActiveUsers([...activeUsers, data.data.userData]); + }); + }); + + socket.on('userDisConnectRespones', (data: any) => { + if (!groupRef.current) return; + if (socket.id === data.socketId || organization !== data.organization) return; + + setCams((prev) => prev.filter((cam) => cam.uuid !== data.data.userData._id)); + setActiveUsers(activeUsers.filter((user: any) => user._id !== data.data.userData._id)); + }); + + socket.on('cameraUpdateResponse', (data: any) => { + if (!groupRef.current || socket.id === data.socketId || organization !== data.organization) return; + + setModels((prev) => ({ + ...prev, + [data.data.userId]: { + targetPosition: new THREE.Vector3(data.data.position.x, data.data.position.y, data.data.position.z), + targetRotation: new THREE.Euler(data.data.rotation.x, data.data.rotation.y, data.data.rotation.z), + }, + })); + }); + + return () => { + socket.off('userConnectRespones'); + socket.off('userDisConnectRespones'); + socket.off('cameraUpdateResponse'); + }; + }, [socket]); + + useFrame(() => { + if (!groupRef.current) return; + Object.keys(models).forEach((uuid) => { + const model = groupRef.current!.getObjectByProperty('uuid', uuid); + if (!model) return; + + const { targetPosition, targetRotation } = models[uuid]; + model.position.lerp(targetPosition, 0.1); + model.rotation.x = THREE.MathUtils.lerp(model.rotation.x, targetRotation.x, 0.1); + model.rotation.y = THREE.MathUtils.lerp(model.rotation.y, targetRotation.y, 0.1); + model.rotation.z = THREE.MathUtils.lerp(model.rotation.z, targetRotation.z, 0.1); + }); + }); + + useEffect(() => { + if (!groupRef.current) return; + const organization = email!.split('@')[1].split('.')[0]; + getActiveUsersData(organization).then((data) => { + const filteredData = data.cameraDatas.filter((camera: any) => camera.userData.email !== email); + if (filteredData.length > 0) { + loader.load(camModel, (gltf) => { + const newCams = filteredData.map((cam: any) => { + const newModel = gltf.scene.clone(); + newModel.uuid = cam.userData._id; + newModel.position.set(cam.position.x, cam.position.y, cam.position.z); + newModel.rotation.set(cam.rotation.x, cam.rotation.y, cam.rotation.z); + newModel.userData = cam.userData; + setActiveUsers([...activeUsers, cam.userData]); + return newModel; + }); + setCams((prev) => [...prev, ...newCams]); + }); + } + }); + }, []); + + return ( + + {cams.map((cam, index) => ( + + + + + + ))} + + ); +}; + +export default CamModelsGroup; diff --git a/frontend/src/components/scene/collab/collabUserIcon.tsx b/frontend/src/components/scene/collab/collabUserIcon.tsx new file mode 100644 index 0000000..4113f6a --- /dev/null +++ b/frontend/src/components/scene/collab/collabUserIcon.tsx @@ -0,0 +1,53 @@ +import React from "react"; + +interface CollabUserIconProps { + color: string; + userImage: string; + userName: string; +} + +const CollabUserIcon: React.FC = ({ + color, + userImage, + userName, +}) => { + return ( +
+ {userName} +
+ {userName} +
+
+ ); +}; + +export default CollabUserIcon; diff --git a/frontend/src/components/scene/collab/socketResponses.dev.tsx b/frontend/src/components/scene/collab/socketResponses.dev.tsx new file mode 100644 index 0000000..a250935 --- /dev/null +++ b/frontend/src/components/scene/collab/socketResponses.dev.tsx @@ -0,0 +1,705 @@ +import { useEffect } from "react"; +import * as THREE from 'three'; +import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; +import gsap from 'gsap'; +import { toast } from 'react-toastify'; +import { useSocketStore, useActiveLayer, useWallItems, useFloorItems, useLayers, useUpdateScene, useWalls, useDeletedLines, useNewLines } from "../../../store/store"; + +import * as Types from "../world/worldTypes"; +import * as CONSTANTS from '../world/worldConstants'; +import TempLoader from "../geomentries/assets/tempLoader"; + +import { setFloorItemApi } from "../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi"; +import objectLineToArray from "../geomentries/lines/lineConvertions/objectLineToArray"; +import addLineToScene from "../geomentries/lines/addLineToScene"; +import updateLinesPositions from "../geomentries/lines/updateLinesPositions"; +import updateLines from "../geomentries/lines/updateLines"; +import updateDistanceText from "../../3d-ui/functions/updateDistanceText"; +import updateFloorLines from "../geomentries/floors/updateFloorLines"; +import loadWalls from "../geomentries/walls/loadWalls"; +import deletePoint from "../geomentries/points/deletePoint"; +import RemoveConnectedLines from "../geomentries/lines/removeConnectedLines"; +import Layer2DVisibility from "../geomentries/layers/layer2DVisibility"; +import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader"; +import { retrieveGLTF, storeGLTF } from "../indexDB/idbUtils"; + + +export default function SocketResponses({ + floorPlanGroup, + lines, + floorGroup, + floorGroupAisle, + scene, + onlyFloorlines, + AssetConfigurations, + itemsGroup, + isTempLoader, + tempLoader, + currentLayerPoint, + floorPlanGroupPoint, + floorPlanGroupLine, + zoneGroup, + dragPointControls +}: any) { + + const { socket } = useSocketStore(); + const { activeLayer, setActiveLayer } = useActiveLayer(); + const { wallItems, setWallItems } = useWallItems(); + const { layers, setLayers } = useLayers(); + const { floorItems, setFloorItems } = useFloorItems(); + const { updateScene, setUpdateScene } = useUpdateScene(); + const { walls, setWalls } = useWalls(); + const { deletedLines, setDeletedLines } = useDeletedLines(); + const { newLines, setNewLines } = useNewLines(); + + useEffect(() => { + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + if (!socket) return + + socket.on('cameraCreateResponse', (data: any) => { + // console.log('data: ', data); + }) + + socket.on('userConnectRespones', (data: any) => { + // console.log('data: ', data); + }) + + socket.on('userDisConnectRespones', (data: any) => { + // console.log('data: ', data); + }) + + socket.on('cameraUpdateResponse', (data: any) => { + // console.log('data: ', data); + }) + + socket.on('EnvironmentUpdateResponse', (data: any) => { + // console.log('data: ', data); + }) + + socket.on('FloorItemsUpdateResponse', async (data: any) => { + if (socket.id === data.socketId) { + return + } + if (organization !== data.organization) { + return + } + if (data.message === "flooritem created") { + const loader = new GLTFLoader(); + const dracoLoader = new DRACOLoader(); + + dracoLoader.setDecoderPath('https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/'); + loader.setDRACOLoader(dracoLoader); + let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`; + + try { + isTempLoader.current = true; + const cachedModel = THREE.Cache.get(data.data.modelname); + let url; + + if (cachedModel) { + // console.log(`Getting ${data.data.modelname} from cache`); + url = URL.createObjectURL(cachedModel); + } else { + const indexedDBModel = await retrieveGLTF(data.data.modelname); + if (indexedDBModel) { + // console.log(`Getting ${data.data.modelname} from IndexedDB`); + url = URL.createObjectURL(indexedDBModel); + } else { + // console.log(`Getting ${data.data.modelname} from Backend`); + url = `${url_Backend_dwinzo}/api/v1/AssetFile/${data.data.modelfileID}`; + const modelBlob = await fetch(url).then((res) => res.blob()); + await storeGLTF(data.data.modelfileID, modelBlob); + } + } + + loadModel(url); + + } catch (error) { + console.error('Error fetching asset model:', error); + } + + function loadModel(url: string) { + loader.load(url, (gltf) => { + URL.revokeObjectURL(url); + THREE.Cache.remove(url); + const model = gltf.scene; + model.uuid = data.data.modeluuid; + model.userData = { name: data.data.modelname, modelId: data.data.modelFileID }; + model.position.set(...data.data.position as [number, number, number]); + model.rotation.set(data.data.rotation.x, data.data.rotation.y, data.data.rotation.z); + model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap); + + model.traverse((child: any) => { + if (child.isMesh) { + // Clone the material to ensure changes are independent + // child.material = child.material.clone(); + + child.castShadow = true; + child.receiveShadow = true; + } + }); + + itemsGroup.current.add(model); + + if (tempLoader.current) { + tempLoader.current.material.dispose(); + tempLoader.current.geometry.dispose(); + itemsGroup.current.remove(tempLoader.current); + tempLoader.current = undefined; + } + + const newFloorItem: Types.FloorItemType = { + modeluuid: data.data.modeluuid, + modelname: data.data.modelname, + modelfileID: data.data.modelfileID, + position: [...data.data.position as [number, number, number]], + rotation: { + x: model.rotation.x, + y: model.rotation.y, + z: model.rotation.z, + }, + isLocked: data.data.isLocked, + isVisible: data.data.isVisible, + }; + + setFloorItems((prevItems: any) => { + const updatedItems = [...(prevItems || []), newFloorItem]; + localStorage.setItem("FloorItems", JSON.stringify(updatedItems)); + return updatedItems; + }); + + gsap.to(model.position, { y: data.data.position[1], duration: 1.5, ease: 'power2.out' }); + gsap.to(model.scale, { x: 1, y: 1, z: 1, duration: 1.5, ease: 'power2.out', onComplete: () => { toast.success("Model Added!") } }); + + THREE.Cache.add(data.data.modelname, gltf); + }, () => { + TempLoader(new THREE.Vector3(...data.data.position), isTempLoader, tempLoader, itemsGroup); + }); + } + + } else if (data.message === "flooritems updated") { + itemsGroup.current.children.forEach((item: THREE.Group) => { + if (item.uuid === data.data.modeluuid) { + item.position.set(...data.data.position as [number, number, number]); + item.rotation.set(data.data.rotation.x, data.data.rotation.y, data.data.rotation.z); + } + }) + + setFloorItems((prevItems: Types.FloorItems) => { + if (!prevItems) { + return + } + let updatedItem: any = null; + const updatedItems = prevItems.map((item) => { + if (item.modeluuid === data.data.modeluuid) { + updatedItem = { + ...item, + position: [...data.data.position] as [number, number, number], + rotation: { x: data.data.rotation.x, y: data.data.rotation.y, z: data.data.rotation.z, }, + }; + return updatedItem; + } + return item; + }); + return updatedItems; + }) + } + }) + + socket.on('FloorItemsDeleteResponse', (data: any) => { + if (socket.id === data.socketId) { + return + } + if (organization !== data.organization) { + return + } + if (data.message === "flooritem deleted") { + const deletedUUID = data.data.modeluuid; + let items = JSON.parse(localStorage.getItem("FloorItems")!); + + const updatedItems = items.filter( + (item: { modeluuid: string }) => item.modeluuid !== deletedUUID + ); + + const storedItems = JSON.parse(localStorage.getItem("FloorItems") || '[]'); + const updatedStoredItems = storedItems.filter((item: { modeluuid: string }) => item.modeluuid !== deletedUUID); + localStorage.setItem("FloorItems", JSON.stringify(updatedStoredItems)); + + itemsGroup.current.children.forEach((item: any) => { + if (item.uuid === deletedUUID) { + itemsGroup.current.remove(item); + } + }) + setFloorItems(updatedItems); + toast.success("Model Removed!"); + } + }) + + socket.on('Line:response:update', (data: any) => { + if (socket.id === data.socketId) { + return + } + if (organization !== data.organization) { + return + } + if (data.message === "line updated") { + const DraggedUUID = data.data.uuid; + const DraggedPosition = new THREE.Vector3(data.data.position.x, data.data.position.y, data.data.position.z); + + const point = floorPlanGroupPoint.current.getObjectByProperty('uuid', DraggedUUID); + point.position.set(DraggedPosition.x, DraggedPosition.y, DraggedPosition.z); + const affectedLines = updateLinesPositions({ uuid: DraggedUUID, position: DraggedPosition }, lines); + + updateLines(floorPlanGroupLine, affectedLines); + updateDistanceText(scene, floorPlanGroupLine, affectedLines); + updateFloorLines(onlyFloorlines, { uuid: DraggedUUID, position: DraggedPosition }); + + loadWalls(lines, setWalls); + setUpdateScene(true); + + } + }) + + socket.on('Line:response:delete', (data: any) => { + if (socket.id === data.socketId) { + return + } + if (organization !== data.organization) { + return + } + if (data.message === "line deleted") { + const line = objectLineToArray(data.data); + const linePoints = line; + const connectedpoints = [linePoints[0][1], linePoints[1][1]]; + + + onlyFloorlines.current = onlyFloorlines.current.map((floorline: any) => + floorline.filter((line: any) => line[0][1] !== connectedpoints[0] && line[1][1] !== connectedpoints[1]) + ).filter((floorline: any) => floorline.length > 0); + + const removedLine = lines.current.find((item: any) => (item[0][1] === linePoints[0][1] && item[1][1] === linePoints[1][1] || (item[0][1] === linePoints[1][1] && item[1][1] === linePoints[0][1]))); + lines.current = lines.current.filter((item: any) => item !== removedLine); + + floorPlanGroupLine.current.children.forEach((line: any) => { + const linePoints = line.userData.linePoints as [number, string, number][]; + const uuid1 = linePoints[0][1]; + const uuid2 = linePoints[1][1]; + + if ((uuid1 === connectedpoints[0] && uuid2 === connectedpoints[1] || (uuid1 === connectedpoints[1] && uuid2 === connectedpoints[0]))) { + line.material.dispose(); + line.geometry.dispose(); + floorPlanGroupLine.current.remove(line); + setDeletedLines([line.userData.linePoints]) + } + }); + + connectedpoints.forEach((pointUUID) => { + let isConnected = false; + floorPlanGroupLine.current.children.forEach((line: any) => { + const linePoints = line.userData.linePoints; + const uuid1 = linePoints[0][1]; + const uuid2 = linePoints[1][1]; + if (uuid1 === pointUUID || uuid2 === pointUUID) { + isConnected = true; + } + }); + + if (!isConnected) { + floorPlanGroupPoint.current.children.forEach((point: any) => { + if (point.uuid === pointUUID) { + point.material.dispose(); + point.geometry.dispose(); + floorPlanGroupPoint.current.remove(point); + } + }); + } + }); + + loadWalls(lines, setWalls); + setUpdateScene(true); + + toast.success("Line Removed!"); + } + }) + + socket.on('Line:response:delete:point', (data: any) => { + if (socket.id === data.socketId) { + return + } + if (organization !== data.organization) { + return + } + if (data.message === "point deleted") { + const point = floorPlanGroupPoint.current?.getObjectByProperty('uuid', data.data); + point.material.dispose(); + point.geometry.dispose(); + floorPlanGroupPoint.current.remove(point); + + onlyFloorlines.current = onlyFloorlines.current.map((floorline: any) => + floorline.filter((line: any) => line[0][1] !== data.data && line[1][1] !== data.data) + ).filter((floorline: any) => floorline.length > 0); + + RemoveConnectedLines(data.data, floorPlanGroupLine, floorPlanGroupPoint, setDeletedLines, lines); + + loadWalls(lines, setWalls); + setUpdateScene(true); + + toast.success("Point Removed!"); + } + }) + + socket.on('Line:response:delete:layer', async (data: any) => { + if (socket.id === data.socketId) { + return + } + if (organization !== data.organization) { + return + } + if (data.message === "layer deleted") { + setActiveLayer(1) + const removedLayer = data.data; + const removedLines: Types.Lines = lines.current.filter((line: any) => line[0][2] === removedLayer); + + ////////// Remove Points and lines from the removed layer ////////// + + removedLines.forEach(async (line) => { + line.forEach(async (removedPoint) => { + const removableLines: THREE.Mesh[] = []; + const connectedpoints: string[] = []; + + floorPlanGroupLine.current.children.forEach((line: any) => { + const linePoints = line.userData.linePoints as [number, string, number][]; + const uuid1 = linePoints[0][1]; + const uuid2 = linePoints[1][1]; + + if (uuid1 === removedPoint[1] || uuid2 === removedPoint[1]) { + connectedpoints.push(uuid1 === removedPoint[1] ? uuid2 : uuid1); + removableLines.push(line as THREE.Mesh); + } + }); + + if (removableLines.length > 0) { + removableLines.forEach((line: any) => { + lines.current = lines.current.filter((item: any) => JSON.stringify(item) !== JSON.stringify(line.userData.linePoints)); + line.material.dispose(); + line.geometry.dispose(); + floorPlanGroupLine.current.remove(line); + }); + } + + const point = floorPlanGroupPoint.current.getObjectByProperty('uuid', removedPoint[1]); + if (point) { + point.material.dispose(); + point.geometry.dispose(); + floorPlanGroupPoint.current.remove(point) + } + }); + }); + + ////////// Update the remaining lines layer values in the userData and in lines.current ////////// + + let remaining = lines.current.filter((line: any) => line[0][2] !== removedLayer); + let updatedLines: Types.Lines = []; + remaining.forEach((line: any) => { + let newLines = JSON.parse(JSON.stringify(line)); + if (newLines[0][2] > removedLayer) { + newLines[0][2] -= 1; + newLines[1][2] -= 1; + } + + const matchingLine = floorPlanGroupLine.current.children.find((l: any) => l.userData.linePoints[0][1] === line[0][1] && l.userData.linePoints[1][1] === line[1][1]); + if (matchingLine) { + const updatedUserData = JSON.parse(JSON.stringify(matchingLine.userData)); + updatedUserData.linePoints[0][2] = newLines[0][2]; + updatedUserData.linePoints[1][2] = newLines[1][2]; + matchingLine.userData = updatedUserData; + } + updatedLines.push(newLines); + }); + + lines.current = updatedLines; + localStorage.setItem("Lines", JSON.stringify(lines.current)); + + ////////// Also remove OnlyFloorLines and update it in localstorage ////////// + + onlyFloorlines.current = onlyFloorlines.current.filter((floor: any) => { + return floor[0][0][2] !== removedLayer; + }); + const meshToRemove = floorGroup.current?.children.find((mesh: any) => + mesh.name === `Only_Floor_Line_${removedLayer}` + ); + if (meshToRemove) { + meshToRemove.geometry.dispose(); + meshToRemove.material.dispose(); + floorGroup.current?.remove(meshToRemove); + } + + const highestLayer = lines.current.reduce((maxLayer: any, segment: any) => { + segment.forEach((point: any) => { + if (point[2] > maxLayer) { + maxLayer = point[2]; + } + }); + return maxLayer; + }, 0); + + setLayers(highestLayer); + + loadWalls(lines, setWalls); + setUpdateScene(true); + + toast.success("Layer Removed!"); + } + }) + }, [socket]) + + useEffect(() => { + if (!socket) return + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + socket.on('wallItemsDeleteResponse', (data: any) => { + if (socket.id === data.socketId) { + return + } + if (organization !== data.organization) { + return + } + if (data.message === "wallitem deleted") { + const deletedUUID = data.data.modeluuid; + let WallItemsRef = wallItems; + const Items = WallItemsRef.filter((item: any) => item.model?.uuid !== deletedUUID); + + setWallItems([]); + setTimeout(async () => { + WallItemsRef = Items; + setWallItems(WallItemsRef); + const WallItemsForStorage = WallItemsRef.map((item: any) => { + const { model, ...rest } = item; + return { + ...rest, + modeluuid: model?.uuid, + }; + }); + + localStorage.setItem("WallItems", JSON.stringify(WallItemsForStorage)); + toast.success("Model Removed!"); + }, 50); + } + }) + + socket.on('wallItemsUpdateResponse', (data: any) => { + if (socket.id === data.socketId) { + return + } + if (organization !== data.organization) { + return + } + if (data.message === "wallIitem created") { + const loader = new GLTFLoader(); + loader.load(AssetConfigurations[data.data.modelname].modelUrl, async (gltf) => { + const model = gltf.scene; + model.uuid = data.data.modeluuid; + model.children[0].children.forEach((child) => { + if (child.name !== "CSG_REF") { + child.castShadow = true; + child.receiveShadow = true; + } + }); + + const newWallItem = { + type: data.data.type, + model: model, + modelname: data.data.modelname, + scale: data.data.scale, + csgscale: data.data.csgscale, + csgposition: data.data.csgposition, + position: data.data.position, + quaternion: data.data.quaternion + }; + + setWallItems((prevItems: any) => { + const updatedItems = [...prevItems, newWallItem]; + + const WallItemsForStorage = updatedItems.map(item => { + const { model, ...rest } = item; + return { + ...rest, + modeluuid: model?.uuid, + }; + }); + + localStorage.setItem("WallItems", JSON.stringify(WallItemsForStorage)); + toast.success("Model Added!"); + + return updatedItems; + }); + }); + } else if (data.message === "wallIitem updated") { + const updatedUUID = data.data.modeluuid; + + setWallItems((prevItems: any) => { + const updatedItems = prevItems.map((item: any) => { + if (item.model.uuid === updatedUUID) { + return { + ...item, + position: data.data.position, + quaternion: data.data.quaternion, + scale: data.data.scale, + csgscale: data.data.csgscale, + csgposition: data.data.csgposition, + }; + } + return item; + }); + + const WallItemsForStorage = updatedItems.map((item: any) => { + const { model, ...rest } = item; + return { + ...rest, + modeluuid: model?.uuid, + }; + }); + + localStorage.setItem("WallItems", JSON.stringify(WallItemsForStorage)); + toast.success("Model Updated!"); + + return updatedItems; + }); + + } + + }) + + return () => { + socket.off('wallItemsDeleteResponse'); + socket.off('wallItemsUpdateResponse'); + }; + }, [wallItems]) + + function getPointColor(lineType: string | undefined): string { + switch (lineType) { + case CONSTANTS.lineConfig.wallName: return CONSTANTS.pointConfig.wallOuterColor; + case CONSTANTS.lineConfig.floorName: return CONSTANTS.pointConfig.floorOuterColor; + case CONSTANTS.lineConfig.aisleName: return CONSTANTS.pointConfig.aisleOuterColor; + case CONSTANTS.lineConfig.zoneName: return CONSTANTS.pointConfig.zoneOuterColor; + default: return CONSTANTS.pointConfig.defaultOuterColor; + } + } + + function getLineColor(lineType: string | undefined): string { + switch (lineType) { + case CONSTANTS.lineConfig.wallName: return CONSTANTS.lineConfig.wallColor; + case CONSTANTS.lineConfig.floorName: return CONSTANTS.lineConfig.floorColor; + case CONSTANTS.lineConfig.aisleName: return CONSTANTS.lineConfig.aisleColor; + case CONSTANTS.lineConfig.zoneName: return CONSTANTS.lineConfig.zoneColor; + default: return CONSTANTS.lineConfig.defaultColor; + } + } + + useEffect(() => { + if (!socket) return + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + socket.on('Line:response:create', (data: any) => { + if (socket.id === data.socketId) { + return + } + if (organization !== data.organization) { + return + } + if (data.message === "line create") { + const line: Types.Line = objectLineToArray(data.data); + const type = line[0][3]; + const pointColour = getPointColor(type); + const lineColour = getLineColor(type); + setNewLines([line]) + + line.forEach((line) => { + const existingPoint = floorPlanGroupPoint.current?.getObjectByProperty('uuid', line[1]); + if (existingPoint) { + return; + } + const geometry = new THREE.BoxGeometry(...CONSTANTS.pointConfig.boxScale); + const material = new THREE.ShaderMaterial({ + uniforms: { + uColor: { value: new THREE.Color(pointColour) }, // Blue color for the border + uInnerColor: { value: new THREE.Color(CONSTANTS.pointConfig.defaultInnerColor) }, // White color for the inner square + }, + vertexShader: ` + varying vec2 vUv; + + void main() { + vUv = uv; + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); + } + `, + fragmentShader: ` + varying vec2 vUv; + uniform vec3 uColor; + uniform vec3 uInnerColor; + + void main() { + // Define the size of the white square as a proportion of the face + float borderThickness = 0.2; // Adjust this value for border thickness + if (vUv.x > borderThickness && vUv.x < 1.0 - borderThickness && + vUv.y > borderThickness && vUv.y < 1.0 - borderThickness) { + gl_FragColor = vec4(uInnerColor, 1.0); // White inner square + } else { + gl_FragColor = vec4(uColor, 1.0); // Blue border + } + } + `, + }); + const point = new THREE.Mesh(geometry, material); + point.name = "point"; + point.uuid = line[1]; + point.userData = { type: type, color: pointColour }; + point.position.set(line[0].x, line[0].y, line[0].z); + currentLayerPoint.current.push(point); + + floorPlanGroupPoint.current?.add(point); + }) + if (dragPointControls.current) { + dragPointControls.current!.objects = currentLayerPoint.current; + } + addLineToScene( + new THREE.Vector3(line[0][0].x, line[0][0].y, line[0][0].z), + new THREE.Vector3(line[1][0].x, line[1][0].y, line[1][0].z), + lineColour, + line, + floorPlanGroupLine + ) + lines.current.push(line); + + const highestLayer = lines.current.reduce((maxLayer: any, segment: any) => { + segment.forEach((point: any) => { + if (point[2] > maxLayer) { + maxLayer = point[2]; + } + }); + return maxLayer; + }, 0); + + setLayers(highestLayer); + + Layer2DVisibility(activeLayer, floorPlanGroup, floorPlanGroupLine, floorPlanGroupPoint, currentLayerPoint, dragPointControls) + + loadWalls(lines, setWalls); + setUpdateScene(true); + } + }) + + return () => { + socket.off('Line:response:create'); + }; + }, [socket, activeLayer]) + + return ( + <> + ) +} \ No newline at end of file diff --git a/frontend/src/components/scene/controls/controls.tsx b/frontend/src/components/scene/controls/controls.tsx new file mode 100644 index 0000000..cb024a0 --- /dev/null +++ b/frontend/src/components/scene/controls/controls.tsx @@ -0,0 +1,136 @@ +import { CameraControls } from "@react-three/drei"; +import { useRef, useEffect } from "react"; +import { useThree } from "@react-three/fiber"; +import * as THREE from "three"; +import * as CONSTANTS from '../world/worldConstants'; + +import { useSocketStore, useToggleView, useResetCamera } from "../../../store/store"; +import { getCamera } from "../../../services/factoryBuilder/camera/getCameraApi"; +import updateCamPosition from "../camera/updateCameraPosition"; +import CamMode from "../camera/camMode"; +import SwitchView from "../camera/switchView"; + +export default function Controls() { + const controlsRef = useRef(null); + + const { toggleView } = useToggleView(); + const { resetCamera, setResetCamera } = useResetCamera(); + const { socket } = useSocketStore(); + const state = useThree(); + + useEffect(() => { + if (controlsRef.current) { + (controlsRef.current as any).mouseButtons.left = CONSTANTS.thirdPersonControls.leftMouse; + (controlsRef.current as any).mouseButtons.right = CONSTANTS.thirdPersonControls.rightMouse; + } + const email = localStorage.getItem("email"); + const organization = email!.split("@")[1].split(".")[0]; + getCamera(organization, localStorage.getItem("userId")!).then((data) => { + if (data && data.position && data.target) { + controlsRef.current?.setPosition(data.position.x, data.position.y, data.position.z); + controlsRef.current?.setTarget(data.target.x, data.target.y, data.target.z); + } else { + controlsRef.current?.setPosition(...CONSTANTS.threeDimension.defaultPosition); + controlsRef.current?.setTarget(...CONSTANTS.threeDimension.defaultTarget); + } + }) + .catch((error) => console.error("Failed to fetch camera data:", error)); + }, []); + + useEffect(() => { + if (resetCamera) { + controlsRef.current?.setPosition(...CONSTANTS.threeDimension.defaultPosition); + controlsRef.current?.setTarget(...CONSTANTS.threeDimension.defaultTarget); + controlsRef.current?.rotateAzimuthTo(CONSTANTS.threeDimension.defaultAzimuth); + + localStorage.setItem("cameraPosition", JSON.stringify(new THREE.Vector3(...CONSTANTS.threeDimension.defaultPosition))); + localStorage.setItem("controlTarget", JSON.stringify(new THREE.Vector3(...CONSTANTS.threeDimension.defaultTarget))); + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + const camData = { + organization: organization, + userId: localStorage.getItem('userId')!, + position: new THREE.Vector3(...CONSTANTS.threeDimension.defaultPosition), + target: new THREE.Vector3(...CONSTANTS.threeDimension.defaultTarget), + rotation: new THREE.Vector3(...CONSTANTS.threeDimension.defaultRotation), + socketId: socket.id + }; + socket.emit('v1:Camera:set', camData) + + setResetCamera(false); + } + }, [resetCamera]); + + useEffect(() => { + controlsRef.current?.setBoundary(new THREE.Box3(new THREE.Vector3(...CONSTANTS.threeDimension.boundaryBottom), new THREE.Vector3(...CONSTANTS.threeDimension.boundaryTop))); + // state.scene.add(new THREE.Box3Helper(new THREE.Box3(new THREE.Vector3(...CONSTANTS.threeDimension.boundaryBottom), new THREE.Vector3(...CONSTANTS.threeDimension.boundaryTop)), 0xffff00)); + let hasInteracted = false; + let intervalId: NodeJS.Timeout | null = null; + + const handleRest = () => { + if (hasInteracted && controlsRef.current && state.camera.position && !toggleView) { + const position = state.camera.position; + if (position.x === 0 && position.y === 0 && position.z === 0) return; + updateCamPosition(controlsRef, socket, position, state.camera.rotation); + stopInterval(); + } + }; + + const startInterval = () => { + hasInteracted = true; + if (!intervalId) { + intervalId = setInterval(() => { + if (controlsRef.current && !toggleView) { + handleRest(); + } + }, CONSTANTS.camPositionUpdateInterval); + } + }; + + const stopInterval = () => { + if (intervalId) { + clearInterval(intervalId); + intervalId = null; + } + }; + + const controls = controlsRef.current; + if (controls) { + controls.addEventListener("sleep", handleRest); + controls.addEventListener("control", startInterval); + controls.addEventListener("controlend", stopInterval); + } + + return () => { + if (controls) { + controls.removeEventListener("sleep", handleRest); + controls.removeEventListener("control", startInterval); + controls.removeEventListener("controlend", stopInterval); + } + stopInterval(); + }; + }, [toggleView, state, socket]); + + return ( + <> + + + + + + ); +} \ No newline at end of file diff --git a/frontend/src/components/scene/controls/selection/boundingBoxHelper.tsx b/frontend/src/components/scene/controls/selection/boundingBoxHelper.tsx new file mode 100644 index 0000000..e725a7f --- /dev/null +++ b/frontend/src/components/scene/controls/selection/boundingBoxHelper.tsx @@ -0,0 +1,62 @@ +import { Line } from "@react-three/drei"; +import { useMemo } from "react"; +import * as THREE from "three"; +import { useSelectedAssets } from "../../../../store/store"; + +const BoundingBox = ({ boundingBoxRef }: any) => { + const { selectedAssets } = useSelectedAssets(); + + const { points, boxProps } = useMemo(() => { + if (selectedAssets.length === 0) return { points: [], boxProps: {} }; + + const box = new THREE.Box3(); + selectedAssets.forEach((obj: any) => box.expandByObject(obj.clone())); + + const size = new THREE.Vector3(); + box.getSize(size); + const center = new THREE.Vector3(); + box.getCenter(center); + + const halfSize = size.clone().multiplyScalar(0.5); + const min = center.clone().sub(halfSize); + const max = center.clone().add(halfSize); + + const points: any = [ + [min.x, min.y, min.z], [max.x, min.y, min.z], + [max.x, min.y, min.z], [max.x, max.y, min.z], + [max.x, max.y, min.z], [min.x, max.y, min.z], + [min.x, max.y, min.z], [min.x, min.y, min.z], + + [min.x, min.y, max.z], [max.x, min.y, max.z], + [max.x, min.y, max.z], [max.x, max.y, max.z], + [max.x, max.y, max.z], [min.x, max.y, max.z], + [min.x, max.y, max.z], [min.x, min.y, max.z], + + [min.x, min.y, min.z], [min.x, min.y, max.z], + [max.x, min.y, min.z], [max.x, min.y, max.z], + [max.x, max.y, min.z], [max.x, max.y, max.z], + [min.x, max.y, min.z], [min.x, max.y, max.z], + ]; + + return { + points, + boxProps: { position: center.toArray(), args: size.toArray() } + }; + }, [selectedAssets]); + + return ( + <> + {points.length > 0 && ( + <> + + + + + + + )} + + ); +}; + +export default BoundingBox; diff --git a/frontend/src/components/scene/controls/selection/copyPasteControls.tsx b/frontend/src/components/scene/controls/selection/copyPasteControls.tsx new file mode 100644 index 0000000..88d4df7 --- /dev/null +++ b/frontend/src/components/scene/controls/selection/copyPasteControls.tsx @@ -0,0 +1,205 @@ +import * as THREE from "three"; +import { useEffect, useMemo } from "react"; +import { useFrame, useThree } from "@react-three/fiber"; +import { useFloorItems, useSelectedAssets, useSocketStore, useToggleView } from "../../../../store/store"; +import { toast } from "react-toastify"; +import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi'; +import * as Types from "../../world/worldTypes"; + +const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, selectionGroup, setDuplicatedObjects, boundingBoxRef }: any) => { + const { camera, controls, gl, scene, pointer, raycaster } = useThree(); + const { toggleView } = useToggleView(); + const { selectedAssets, setSelectedAssets } = useSelectedAssets(); + const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []); + const { floorItems, setFloorItems } = useFloorItems(); + const { socket } = useSocketStore() + + useEffect(() => { + if (!camera || !scene || toggleView) return; + const canvasElement = gl.domElement; + canvasElement.tabIndex = 0; + let isSelecting = false; + + const onPointerDown = () => { + isSelecting = false; + }; + + const onPointerMove = () => { + isSelecting = true; + }; + + const onPointerUp = (event: PointerEvent) => { + if (!isSelecting && pastedObjects.length > 0 && event.button === 0) { + event.preventDefault(); + addPastedObjects(); + } + }; + + const onKeyDown = (event: KeyboardEvent) => { + if (event.ctrlKey && event.key.toLowerCase() === "c") { + copySelection(); + } + if (event.ctrlKey && event.key.toLowerCase() === "v" && copiedObjects.length > 0 && pastedObjects.length === 0) { + pasteCopiedObjects(); + } + }; + + if (!toggleView) { + canvasElement.addEventListener("pointerdown", onPointerDown); + canvasElement.addEventListener("pointermove", onPointerMove); + canvasElement.addEventListener("pointerup", onPointerUp); + canvasElement.addEventListener("keydown", onKeyDown); + } + + return () => { + canvasElement.removeEventListener("pointerdown", onPointerDown); + canvasElement.removeEventListener("pointermove", onPointerMove); + canvasElement.removeEventListener("pointerup", onPointerUp); + canvasElement.removeEventListener("keydown", onKeyDown); + }; + + }, [camera, controls, scene, toggleView, selectedAssets, copiedObjects, pastedObjects, socket, floorItems]); + + useFrame(() => { + if (pastedObjects.length > 0) { + const intersectionPoint = new THREE.Vector3(); + raycaster.setFromCamera(pointer, camera); + const point = raycaster.ray.intersectPlane(plane, intersectionPoint); + if (point) { + const position = new THREE.Vector3(); + if (boundingBoxRef.current) { + boundingBoxRef.current?.getWorldPosition(position) + selectionGroup.current.position.set(point.x - (position.x - selectionGroup.current.position.x), selectionGroup.current.position.y, point.z - (position.z - selectionGroup.current.position.z)); + } else { + const box = new THREE.Box3(); + pastedObjects.forEach((obj: THREE.Object3D) => box.expandByObject(obj.clone())); + const center = new THREE.Vector3(); + box.getCenter(center); + selectionGroup.current.position.set(point.x - (center.x - selectionGroup.current.position.x), selectionGroup.current.position.y, point.z - (center.z - selectionGroup.current.position.z)); + } + } + } + }); + + const copySelection = () => { + if (selectedAssets.length > 0) { + const newClones = selectedAssets.map((asset: any) => { + const clone = asset.clone(); + clone.position.copy(asset.position); + return clone; + }); + setCopiedObjects(newClones); + toast.info("Objects copied!"); + } + }; + + const pasteCopiedObjects = () => { + if (copiedObjects.length > 0 && pastedObjects.length === 0) { + const newClones = copiedObjects.map((obj: THREE.Object3D) => { + const clone = obj.clone(); + clone.position.copy(obj.position); + return clone; + }); + selectionGroup.current.add(...newClones); + setpastedObjects([...newClones]); + setSelectedAssets([...newClones]); + + const intersectionPoint = new THREE.Vector3(); + raycaster.setFromCamera(pointer, camera); + const point = raycaster.ray.intersectPlane(plane, intersectionPoint); + + if (point) { + const position = new THREE.Vector3(); + if (boundingBoxRef.current) { + boundingBoxRef.current?.getWorldPosition(position) + selectionGroup.current.position.set(point.x - (position.x - selectionGroup.current.position.x), selectionGroup.current.position.y, point.z - (position.z - selectionGroup.current.position.z)); + } else { + const box = new THREE.Box3(); + newClones.forEach((obj: THREE.Object3D) => box.expandByObject(obj.clone())); + const center = new THREE.Vector3(); + box.getCenter(center); + selectionGroup.current.position.set(point.x - (center.x - selectionGroup.current.position.x), selectionGroup.current.position.y, point.z - (center.z - selectionGroup.current.position.z)); + } + } + } + }; + + const addPastedObjects = () => { + if (pastedObjects.length === 0) return; + pastedObjects.forEach(async (obj: THREE.Object3D) => { + const worldPosition = new THREE.Vector3(); + obj.getWorldPosition(worldPosition); + obj.position.copy(worldPosition); + + if (itemsGroupRef.current) { + + const newFloorItem: Types.FloorItemType = { + modeluuid: obj.uuid, + modelname: obj.userData.name, + modelfileID: obj.userData.modelId, + position: [worldPosition.x, worldPosition.y, worldPosition.z], + rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z, }, + isLocked: false, + isVisible: true + }; + + setFloorItems((prevItems: Types.FloorItems) => { + const updatedItems = [...(prevItems || []), newFloorItem]; + localStorage.setItem("FloorItems", JSON.stringify(updatedItems)); + return updatedItems; + }); + + const email = localStorage.getItem("email"); + const organization = email ? email.split("@")[1].split(".")[0] : "default"; + + //REST + + // await setFloorItemApi( + // organization, + // obj.uuid, + // obj.userData.name, + // [worldPosition.x, worldPosition.y, worldPosition.z], + // { "x": obj.rotation.x, "y": obj.rotation.y, "z": obj.rotation.z }, + // obj.userData.modelId, + // false, + // true, + // ); + + //SOCKET + + const data = { + organization, + modeluuid: newFloorItem.modeluuid, + modelname: newFloorItem.modelname, + modelfileID: newFloorItem.modelfileID, + position: newFloorItem.position, + rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z }, + isLocked: false, + isVisible: true, + socketId: socket.id, + }; + + socket.emit("v1:FloorItems:set", data); + + itemsGroupRef.current.add(obj); + toast.success("Object added!"); + } + }); + + clearSelection(); + }; + + const clearSelection = () => { + selectionGroup.current.children = []; + selectionGroup.current.position.set(0, 0, 0); + setpastedObjects([]); + setDuplicatedObjects([]); + setSelectedAssets([]); + } + + return ( + <> + ); +}; + +export default CopyPasteControls; \ No newline at end of file diff --git a/frontend/src/components/scene/controls/selection/duplicationControls.tsx b/frontend/src/components/scene/controls/selection/duplicationControls.tsx new file mode 100644 index 0000000..fe9e731 --- /dev/null +++ b/frontend/src/components/scene/controls/selection/duplicationControls.tsx @@ -0,0 +1,184 @@ +import * as THREE from "three"; +import { useEffect, useMemo } from "react"; +import { useFrame, useThree } from "@react-three/fiber"; +import { useFloorItems, useSelectedAssets, useSocketStore, useToggleView } from "../../../../store/store"; +import { toast } from "react-toastify"; +import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi'; +import * as Types from "../../world/worldTypes"; + +const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedObjects, setpastedObjects, selectionGroup, boundingBoxRef }: any) => { + const { camera, controls, gl, scene, pointer, raycaster } = useThree(); + const { toggleView } = useToggleView(); + const { selectedAssets, setSelectedAssets } = useSelectedAssets(); + const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []); + const { floorItems, setFloorItems } = useFloorItems(); + const { socket } = useSocketStore(); + + + useEffect(() => { + if (!camera || !scene || toggleView) return; + const canvasElement = gl.domElement; + canvasElement.tabIndex = 0; + let isSelecting = false; + + const onPointerDown = () => { + isSelecting = false; + }; + + const onPointerMove = () => { + isSelecting = true; + }; + + const onPointerUp = (event: PointerEvent) => { + if (!isSelecting && duplicatedObjects.length > 0 && event.button === 0) { + event.preventDefault(); + addDuplicatedAssets(); + } + }; + + const onKeyDown = (event: KeyboardEvent) => { + if (event.ctrlKey && event.key.toLowerCase() === "d" && selectedAssets.length > 0 && duplicatedObjects.length === 0) { + event.preventDefault(); + duplicateSelection(); + } + }; + + if (!toggleView) { + canvasElement.addEventListener("pointerdown", onPointerDown); + canvasElement.addEventListener("pointermove", onPointerMove); + canvasElement.addEventListener("pointerup", onPointerUp); + canvasElement.addEventListener("keydown", onKeyDown); + } + + return () => { + canvasElement.removeEventListener("pointerdown", onPointerDown); + canvasElement.removeEventListener("pointermove", onPointerMove); + canvasElement.removeEventListener("pointerup", onPointerUp); + canvasElement.removeEventListener("keydown", onKeyDown); + }; + + }, [camera, controls, scene, toggleView, selectedAssets, duplicatedObjects, socket, floorItems]); + + useFrame(() => { + if (duplicatedObjects.length > 0) { + const intersectionPoint = new THREE.Vector3(); + raycaster.setFromCamera(pointer, camera); + const point = raycaster.ray.intersectPlane(plane, intersectionPoint); + if (point) { + const position = new THREE.Vector3(); + if (boundingBoxRef.current) { + boundingBoxRef.current?.getWorldPosition(position) + selectionGroup.current.position.set(point.x - (position.x - selectionGroup.current.position.x), selectionGroup.current.position.y, point.z - (position.z - selectionGroup.current.position.z)); + } else { + const box = new THREE.Box3(); + duplicatedObjects.forEach((obj: THREE.Object3D) => box.expandByObject(obj.clone())); + const center = new THREE.Vector3(); + box.getCenter(center); + selectionGroup.current.position.set(point.x - (center.x - selectionGroup.current.position.x), selectionGroup.current.position.y, point.z - (center.z - selectionGroup.current.position.z)); + } + } + } + }); + + const duplicateSelection = () => { + if (selectedAssets.length > 0 && duplicatedObjects.length === 0) { + const newClones = selectedAssets.map((asset: any) => { + const clone = asset.clone(); + clone.position.copy(asset.position); + return clone; + }); + + selectionGroup.current.add(...newClones); + setDuplicatedObjects(newClones); + + const intersectionPoint = new THREE.Vector3(); + raycaster.setFromCamera(pointer, camera); + const point = raycaster.ray.intersectPlane(plane, intersectionPoint); + + if (point) { + const position = new THREE.Vector3(); + boundingBoxRef.current?.getWorldPosition(position) + selectionGroup.current.position.set(point.x - (position.x - selectionGroup.current.position.x), selectionGroup.current.position.y, point.z - (position.z - selectionGroup.current.position.z)); + } + } + }; + + const addDuplicatedAssets = () => { + if (duplicatedObjects.length === 0) return; + duplicatedObjects.forEach(async (obj: THREE.Object3D) => { + const worldPosition = new THREE.Vector3(); + obj.getWorldPosition(worldPosition); + obj.position.copy(worldPosition); + + if (itemsGroupRef.current) { + + const newFloorItem: Types.FloorItemType = { + modeluuid: obj.uuid, + modelname: obj.userData.name, + modelfileID: obj.userData.modelId, + position: [worldPosition.x, worldPosition.y, worldPosition.z], + rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z, }, + isLocked: false, + isVisible: true + }; + + setFloorItems((prevItems: Types.FloorItems) => { + const updatedItems = [...(prevItems || []), newFloorItem]; + localStorage.setItem("FloorItems", JSON.stringify(updatedItems)); + return updatedItems; + }); + + const email = localStorage.getItem("email"); + const organization = email ? email.split("@")[1].split(".")[0] : "default"; + + //REST + + // await setFloorItemApi( + // organization, + // obj.uuid, + // obj.userData.name, + // [worldPosition.x, worldPosition.y, worldPosition.z], + // { "x": obj.rotation.x, "y": obj.rotation.y, "z": obj.rotation.z }, + // obj.userData.modelId, + // false, + // true, + // ); + + //SOCKET + + const data = { + organization, + modeluuid: newFloorItem.modeluuid, + modelname: newFloorItem.modelname, + modelfileID: newFloorItem.modelfileID, + position: newFloorItem.position, + rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z }, + isLocked: false, + isVisible: true, + socketId: socket.id, + }; + + socket.emit("v1:FloorItems:set", data); + + itemsGroupRef.current.add(obj); + toast.success("Object duplicated!"); + } + }); + + clearSelection(); + } + + const clearSelection = () => { + selectionGroup.current.children = []; + selectionGroup.current.position.set(0, 0, 0); + setpastedObjects([]); + setDuplicatedObjects([]); + setSelectedAssets([]); + } + + return ( + <> + ); +}; + +export default DuplicationControls; \ No newline at end of file diff --git a/frontend/src/components/scene/controls/selection/selectionControls.tsx b/frontend/src/components/scene/controls/selection/selectionControls.tsx new file mode 100644 index 0000000..b31d8c0 --- /dev/null +++ b/frontend/src/components/scene/controls/selection/selectionControls.tsx @@ -0,0 +1,217 @@ +import * as THREE from "three"; +import { useEffect, useMemo, useRef, useState } from "react"; +import { SelectionBox } from "three/examples/jsm/interactive/SelectionBox"; +import { SelectionHelper } from "./selectionHelper"; +import { useFrame, useThree } from "@react-three/fiber"; +import { useFloorItems, useSelectedAssets, useSocketStore, useToggleView } from "../../../../store/store"; +import BoundingBox from "./boundingBoxHelper"; +import { toast } from "react-toastify"; +import { deleteFloorItem } from '../../../../services/factoryBuilder/assest/floorAsset/deleteFloorItemApi'; +import * as Types from "../../world/worldTypes"; + +import DuplicationControls from "./duplicationControls"; +import CopyPasteControls from "./copyPasteControls"; + +const SelectionControls: React.FC = () => { + const { camera, controls, gl, scene, pointer } = useThree(); + const itemsGroupRef = useRef(undefined); + const selectionGroup = useRef() as Types.RefGroup; + const { toggleView } = useToggleView(); + const { selectedAssets, setSelectedAssets } = useSelectedAssets(); + const [copiedObjects, setCopiedObjects] = useState([]); + const [pastedObjects, setpastedObjects] = useState([]); + const [duplicatedObjects, setDuplicatedObjects] = useState([]); + const boundingBoxRef = useRef(); + const { floorItems, setFloorItems } = useFloorItems(); + const { socket } = useSocketStore(); + const selectionBox = useMemo(() => new SelectionBox(camera, scene), [camera, scene]); + + useEffect(() => { + if (!camera || !scene || toggleView) return; + + const canvasElement = gl.domElement; + canvasElement.tabIndex = 0; + + const itemsGroup: any = scene.getObjectByName("itemsGroup"); + itemsGroupRef.current = itemsGroup; + let isSelecting = false; + + const helper = new SelectionHelper(gl); + + if (!itemsGroup) { + toast.warn("itemsGroup not found in the scene."); + return; + } + + const onPointerDown = (event: PointerEvent) => { + isSelecting = false; + if (event.ctrlKey && duplicatedObjects.length === 0) { + if (controls) (controls as any).enabled = false; + selectionBox.startPoint.set(pointer.x, pointer.y, 0); + } + }; + + const onPointerMove = (event: PointerEvent) => { + isSelecting = true; + if (helper.isDown && event.ctrlKey && duplicatedObjects.length === 0) { + selectionBox.endPoint.set(pointer.x, pointer.y, 0); + } + }; + + const onPointerUp = (event: PointerEvent) => { + if (isSelecting) { + isSelecting = false; + if (event.ctrlKey && duplicatedObjects.length === 0) { + selectAssets(); + } + } else if (!isSelecting && selectedAssets.length > 0 && ((pastedObjects.length === 0 && duplicatedObjects.length === 0) || event.button !== 0)) { + clearSelection(); + helper.enabled = true; + } + }; + + const onKeyDown = (event: KeyboardEvent) => { + if (event.key.toLowerCase() === "escape") { + event.preventDefault(); + clearSelection(); + } + if (event.key.toLowerCase() === "delete") { + event.preventDefault(); + deleteSelection(); + } + }; + + if (!toggleView) { + helper.enabled = true; + canvasElement.addEventListener("pointerdown", onPointerDown); + canvasElement.addEventListener("pointermove", onPointerMove); + canvasElement.addEventListener("pointerup", onPointerUp); + canvasElement.addEventListener("keydown", onKeyDown); + } + + return () => { + canvasElement.removeEventListener("pointerdown", onPointerDown); + canvasElement.removeEventListener("pointermove", onPointerMove); + canvasElement.removeEventListener("pointerup", onPointerUp); + canvasElement.removeEventListener("keydown", onKeyDown); + helper.enabled = false; + helper.dispose(); + }; + }, [camera, controls, scene, toggleView, selectedAssets, copiedObjects, pastedObjects, duplicatedObjects, socket, floorItems]); + + + useFrame(() => { + if (pastedObjects.length === 0 && duplicatedObjects.length === 0) { + selectionGroup.current.position.set(0, 0, 0); + } + }); + + const selectAssets = () => { + selectionBox.endPoint.set(pointer.x, pointer.y, 0); + if (controls) (controls as any).enabled = true; + + let selectedObjects = selectionBox.select(); + let Objects = new Set(); + + selectedObjects.map((object) => { + let currentObject: THREE.Object3D | null = object; + while (currentObject) { + if (currentObject.userData.modelId) { + Objects.add(currentObject); + break; + } + currentObject = currentObject.parent || null; + } + }) + + if (Objects.size === 0) { + clearSelection(); + return; + } + + const updatedSelections = new Set(selectedAssets); + Objects.forEach((obj) => { + updatedSelections.has(obj) ? updatedSelections.delete(obj) : updatedSelections.add(obj); + }); + + const selected = Array.from(updatedSelections); + + setSelectedAssets(selected); + }; + + const clearSelection = () => { + selectionGroup.current.children = []; + selectionGroup.current.position.set(0, 0, 0); + setpastedObjects([]); + setDuplicatedObjects([]); + setSelectedAssets([]); + } + + const deleteSelection = () => { + if (selectedAssets.length > 0 && duplicatedObjects.length === 0) { + const email = localStorage.getItem('email'); + const organization = (email!.split("@")[1]).split(".")[0]; + + const storedItems = JSON.parse(localStorage.getItem("FloorItems") || '[]'); + const selectedUUIDs = selectedAssets.map((mesh: THREE.Object3D) => mesh.uuid); + + const updatedStoredItems = storedItems.filter((item: { modeluuid: string }) => !selectedUUIDs.includes(item.modeluuid)); + localStorage.setItem("FloorItems", JSON.stringify(updatedStoredItems)); + + selectedAssets.forEach((selectedMesh: THREE.Object3D) => { + + //REST + + // const response = await deleteFloorItem(organization, selectedMesh.uuid, selectedMesh.userData.name); + + //SOCKET + + const data = { + organization: organization, + modeluuid: selectedMesh.uuid, + modelname: selectedMesh.userData.name, + socketId: socket.id + }; + + socket.emit('v1:FloorItems:delete', data); + + selectedMesh.traverse((child: THREE.Object3D) => { + if (child instanceof THREE.Mesh) { + if (child.geometry) child.geometry.dispose(); + if (Array.isArray(child.material)) { + child.material.forEach((material) => { + if (material.map) material.map.dispose(); + material.dispose(); + }); + } else if (child.material) { + if (child.material.map) child.material.map.dispose(); + child.material.dispose(); + } + } + }); + + itemsGroupRef.current?.remove(selectedMesh); + }); + + const updatedItems = floorItems.filter((item: { modeluuid: string }) => !selectedUUIDs.includes(item.modeluuid)); + setFloorItems(updatedItems); + + toast.success("Selected models removed!"); + } + clearSelection(); + }; + + return ( + <> + + + + + + + + + ); +}; + +export default SelectionControls; \ No newline at end of file diff --git a/frontend/src/components/scene/controls/selection/selectionHelper.ts b/frontend/src/components/scene/controls/selection/selectionHelper.ts new file mode 100644 index 0000000..c1acaf6 --- /dev/null +++ b/frontend/src/components/scene/controls/selection/selectionHelper.ts @@ -0,0 +1,115 @@ +import { Vector2, WebGLRenderer } from 'three'; + +class SelectionHelper { + element: HTMLDivElement; + renderer: WebGLRenderer; + startPoint: Vector2; + pointTopLeft: Vector2; + pointBottomRight: Vector2; + isDown: boolean; + enabled: boolean; + + constructor(renderer: WebGLRenderer) { + this.element = document.createElement('div'); + this.element.style.position = 'fixed'; + this.element.style.border = '1px solid #55aaff'; + this.element.style.backgroundColor = 'rgba(75, 160, 255, 0.3)'; + this.element.style.pointerEvents = 'none'; + this.element.style.display = 'none'; + + this.renderer = renderer; + + this.startPoint = new Vector2(); + this.pointTopLeft = new Vector2(); + this.pointBottomRight = new Vector2(); + + this.isDown = false; + this.enabled = true; + + this.onPointerDown = this.onPointerDown.bind(this); + this.onPointerMove = this.onPointerMove.bind(this); + this.onPointerUp = this.onPointerUp.bind(this); + + this.renderer.domElement.addEventListener('pointerdown', this.onPointerDown); + this.renderer.domElement.addEventListener('pointermove', this.onPointerMove); + this.renderer.domElement.addEventListener('pointerup', this.onPointerUp); + window.addEventListener("blur", this.cleanup.bind(this)); + } + + dispose() { + this.enabled = false; + this.isDown = false; + this.cleanup(); + + this.renderer.domElement.removeEventListener("pointerdown", this.onPointerDown); + this.renderer.domElement.removeEventListener("pointermove", this.onPointerMove); + this.renderer.domElement.removeEventListener("pointerup", this.onPointerUp); + window.removeEventListener("blur", this.cleanup); + } + + private cleanup() { + this.isDown = false; + this.element.style.display = 'none'; + if (this.element.parentElement) { + this.element.parentElement.removeChild(this.element); + } + } + + onPointerDown(event: PointerEvent) { + if (!this.enabled || !event.ctrlKey || event.button !== 0) return; + + this.isDown = true; + this.onSelectStart(event); + } + + onPointerMove(event: PointerEvent) { + if (!this.enabled || !this.isDown || !event.ctrlKey) return; + + this.onSelectMove(event); + } + + onPointerUp() { + if (!this.enabled) return; + + this.isDown = false; + this.onSelectOver(); + } + + onSelectStart(event: PointerEvent) { + this.element.style.display = 'none'; + this.renderer.domElement.parentElement?.appendChild(this.element); + + this.element.style.left = `${event.clientX}px`; + this.element.style.top = `${event.clientY}px`; + this.element.style.width = '0px'; + this.element.style.height = '0px'; + + this.startPoint.x = event.clientX; + this.startPoint.y = event.clientY; + } + + onSelectMove(event: PointerEvent) { + if (!this.isDown) return; + + this.element.style.display = 'block'; + + this.pointBottomRight.x = Math.max(this.startPoint.x, event.clientX); + this.pointBottomRight.y = Math.max(this.startPoint.y, event.clientY); + this.pointTopLeft.x = Math.min(this.startPoint.x, event.clientX); + this.pointTopLeft.y = Math.min(this.startPoint.y, event.clientY); + + this.element.style.left = `${this.pointTopLeft.x}px`; + this.element.style.top = `${this.pointTopLeft.y}px`; + this.element.style.width = `${this.pointBottomRight.x - this.pointTopLeft.x}px`; + this.element.style.height = `${this.pointBottomRight.y - this.pointTopLeft.y}px`; + } + + onSelectOver() { + this.element.style.display = 'none'; + if (this.element.parentElement) { + this.element.parentElement.removeChild(this.element); + } + } +} + +export { SelectionHelper }; \ No newline at end of file diff --git a/frontend/src/components/scene/controls/transformControls.tsx b/frontend/src/components/scene/controls/transformControls.tsx new file mode 100644 index 0000000..181646c --- /dev/null +++ b/frontend/src/components/scene/controls/transformControls.tsx @@ -0,0 +1,120 @@ +import { TransformControls } from "@react-three/drei"; +import * as THREE from "three"; +import { useselectedFloorItem, useObjectPosition, useObjectScale, useObjectRotation, useTransformMode, useFloorItems, useSocketStore, useActiveTool } from "../../../store/store"; +import { useThree } from "@react-three/fiber"; + +import * as Types from '../world/worldTypes' +import { useEffect } from "react"; + +export default function TransformControl() { + const state = useThree(); + const { selectedFloorItem, setselectedFloorItem } = useselectedFloorItem(); + const { objectPosition, setObjectPosition } = useObjectPosition(); + const { objectScale, setObjectScale } = useObjectScale(); + const { objectRotation, setObjectRotation } = useObjectRotation(); + const { transformMode, setTransformMode } = useTransformMode(); + const { floorItems, setFloorItems } = useFloorItems(); + const { activeTool, setActiveTool } = useActiveTool(); + const { socket } = useSocketStore(); + + function handleObjectChange() { + if (selectedFloorItem && transformMode) { + setObjectPosition(selectedFloorItem.position); + setObjectScale(selectedFloorItem.scale); + setObjectRotation({ + x: THREE.MathUtils.radToDeg(selectedFloorItem.rotation.x), + y: THREE.MathUtils.radToDeg(selectedFloorItem.rotation.y), + z: THREE.MathUtils.radToDeg(selectedFloorItem.rotation.z), + }); + } + } + function handleMouseUp() { + if (selectedFloorItem) { + setObjectPosition(selectedFloorItem.position); + setObjectScale(selectedFloorItem.scale); + setObjectRotation({ + x: THREE.MathUtils.radToDeg(selectedFloorItem.rotation.x), + y: THREE.MathUtils.radToDeg(selectedFloorItem.rotation.y), + z: THREE.MathUtils.radToDeg(selectedFloorItem.rotation.z), + }); + } + setFloorItems((prevItems: Types.FloorItems) => { + if (!prevItems) { + return + } + let updatedItem: any = null; + const updatedItems = prevItems.map((item) => { + if (item.modeluuid === selectedFloorItem?.uuid) { + updatedItem = { + ...item, + position: [selectedFloorItem.position.x, selectedFloorItem.position.y, selectedFloorItem.position.z,] as [number, number, number], + rotation: { x: selectedFloorItem.rotation.x, y: selectedFloorItem.rotation.y, z: selectedFloorItem.rotation.z, }, + }; + return updatedItem; + } + return item; + }); + if (updatedItem && selectedFloorItem) { + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // setFloorItemApi( + // organization, + // updatedItem.modeluuid, + // updatedItem.modelname, + // [selectedFloorItem.position.x, selectedFloorItem.position.y, selectedFloorItem.position.z,], + // { "x": selectedFloorItem.rotation.x, "y": selectedFloorItem.rotation.y, "z": selectedFloorItem.rotation.z }, + // false, + // true, + // ); + + //SOCKET + + const data = { + organization: organization, + modeluuid: updatedItem.modeluuid, + modelname: updatedItem.modelname, + position: [selectedFloorItem.position.x, selectedFloorItem.position.y, selectedFloorItem.position.z], + rotation: { "x": selectedFloorItem.rotation.x, "y": selectedFloorItem.rotation.y, "z": selectedFloorItem.rotation.z }, + isLocked: false, + isVisible: true, + socketId: socket.id + } + + socket.emit('v1:FloorItems:set', data); + } + localStorage.setItem("FloorItems", JSON.stringify(updatedItems)); + return updatedItems; + }); + } + + useEffect(() => { + if (activeTool === "Add pillar" || activeTool === "Delete") { + if (state.controls) { + const target = (state.controls as any).getTarget(new THREE.Vector3()); + (state.controls as any).setTarget(target.x, 0, target.z, true); + } + setselectedFloorItem(null); + { + setObjectPosition({ x: undefined, y: undefined, z: undefined }); + setObjectScale({ x: undefined, y: undefined, z: undefined }); + setObjectRotation({ x: undefined, y: undefined, z: undefined }); + } + } + }, [activeTool]); + + return ( + <> + {(selectedFloorItem && transformMode) && + + } + + ); +} diff --git a/frontend/src/components/scene/csg/csg.tsx b/frontend/src/components/scene/csg/csg.tsx new file mode 100644 index 0000000..0926710 --- /dev/null +++ b/frontend/src/components/scene/csg/csg.tsx @@ -0,0 +1,54 @@ +import * as THREE from "three"; +import { Geometry, Base, Subtraction } from "@react-three/csg"; +import { useDeleteModels } from "../../../store/store"; +import { useRef } from "react"; + +export interface CsgProps { + position: THREE.Vector3 | [number, number, number]; + scale: THREE.Vector3 | [number, number, number]; + model: THREE.Object3D; + hoveredDeletableWallItem: { current: THREE.Mesh | null }; +} + +export const Csg: React.FC = (props) => { + const { deleteModels } = useDeleteModels(); + const modelRef = useRef(); + const originalMaterials = useRef>(new Map()); + + const handleHover = (hovered: boolean, object: THREE.Mesh | null) => { + if (modelRef.current && deleteModels) { + modelRef.current.traverse((child) => { + if (child instanceof THREE.Mesh) { + if (!originalMaterials.current.has(child)) { + originalMaterials.current.set(child, child.material); + } + child.material = child.material.clone(); + child.material.color.set(hovered && deleteModels ? 0xff0000 : (originalMaterials.current.get(child) as any).color); + } + }); + } + props.hoveredDeletableWallItem.current = hovered ? object : null; + }; + + return ( + + + + + + + { + e.stopPropagation(); + handleHover(true, e.object.parent); + }} + onPointerOut={(e: any) => { + e.stopPropagation(); + handleHover(false, null); + }} + /> + + ); +}; diff --git a/frontend/src/components/scene/environment/ground.tsx b/frontend/src/components/scene/environment/ground.tsx new file mode 100644 index 0000000..726579d --- /dev/null +++ b/frontend/src/components/scene/environment/ground.tsx @@ -0,0 +1,22 @@ +import * as THREE from 'three'; +import { useToggleView } from '../../../store/store'; +import * as CONSTANTS from '../world/worldConstants'; + +const Ground = ({ grid, plane }: any) => { + const { toggleView, setToggleView } = useToggleView(); + + return ( + + + + + + + + + + + ) +} + +export default Ground; \ No newline at end of file diff --git a/frontend/src/components/scene/environment/shadow.tsx b/frontend/src/components/scene/environment/shadow.tsx new file mode 100644 index 0000000..ef4c4a0 --- /dev/null +++ b/frontend/src/components/scene/environment/shadow.tsx @@ -0,0 +1,84 @@ +import { useRef, useEffect, useState } from 'react'; +import { useThree } from '@react-three/fiber'; +import * as THREE from 'three'; +import { useAzimuth, useElevation, useShadows, useSunPosition, useFloorItems, useWallItems } from '../../../store/store'; +import * as CONSTANTS from '../world/worldConstants'; +const shadowWorker = new Worker(new URL('../../../services/factoryBuilder/webWorkers/shadowWorker', import.meta.url)); + +export default function Shadows() { + const { shadows, setShadows } = useShadows(); + const { sunPosition, setSunPosition } = useSunPosition(); + const lightRef = useRef(null); + const targetRef = useRef(null); + const { controls, gl } = useThree(); + const { elevation, setElevation } = useElevation(); + const { azimuth, setAzimuth } = useAzimuth(); + const { floorItems } = useFloorItems(); + const { wallItems } = useWallItems(); + + useEffect(() => { + gl.shadowMap.enabled = true; + gl.shadowMap.type = THREE.PCFShadowMap; + }, [gl, floorItems, wallItems]); + + useEffect(() => { + if (lightRef.current && targetRef.current) { + lightRef.current.target = targetRef.current; + } + }, []); + + useEffect(() => { + shadowWorker.onmessage = (event) => { + const { lightPosition, controlsTarget } = event.data; + if (lightRef.current && targetRef.current && controls) { + lightRef.current.position.copy(lightPosition); + targetRef.current.position.copy(controlsTarget); + } + }; + }, [shadowWorker, controls]); + + const updateShadows = () => { + if (controls && shadowWorker) { + const offsetDistance = CONSTANTS.shadowConfig.shadowOffset; + const controlsTarget = (controls as any).getTarget(); + shadowWorker.postMessage({ controlsTarget, sunPosition, offsetDistance }); + } + }; + + useEffect(() => { + if (controls && shadows) { + updateShadows(); + (controls as any).addEventListener('update', updateShadows); + return () => { + (controls as any).removeEventListener('update', updateShadows); + }; + } + }, [controls, elevation, azimuth, shadows]); + + return ( + <> + {/* {(lightRef.current?.shadow) && + + } */} + + + + + + + + ); +} \ No newline at end of file diff --git a/frontend/src/components/scene/environment/sky.tsx b/frontend/src/components/scene/environment/sky.tsx new file mode 100644 index 0000000..77f56f3 --- /dev/null +++ b/frontend/src/components/scene/environment/sky.tsx @@ -0,0 +1,50 @@ +import * as THREE from 'three'; +import * as Types from '../world/worldTypes'; +import { Sky } from "@react-three/drei"; +import { useAzimuth, useElevation, useSunPosition } from "../../../store/store"; +import { useEffect, useRef, useState } from "react"; +import * as CONSTANTS from '../world/worldConstants'; + +export default function Sun() { + const { elevation, setElevation } = useElevation(); + const { sunPosition, setSunPosition } = useSunPosition(); + const { azimuth, setAzimuth } = useAzimuth(); + const [turbidity, setTurbidity] = useState(CONSTANTS.skyConfig.defaultTurbidity); + const sunPositionRef = useRef(new THREE.Vector3(0, 0, 0)); + const [_, forceUpdate] = useState(0); + const maxTurbidity = CONSTANTS.skyConfig.maxTurbidity; + const minTurbidity = CONSTANTS.skyConfig.minTurbidity; + + useEffect(() => { + const phi = THREE.MathUtils.degToRad(90 - elevation); + const theta = THREE.MathUtils.degToRad(azimuth); + + const computedTurbidity = minTurbidity + ((elevation - 2) / (90 - 2)) * (maxTurbidity - minTurbidity); + setTurbidity(computedTurbidity); + + sunPositionRef.current.setFromSphericalCoords(1, phi, theta); + setSunPosition(sunPositionRef.current); + forceUpdate(prev => prev + 1); + }, [elevation, azimuth]); + + return ( + <> + {(azimuth !== undefined && elevation !== undefined) && ( + <> + + + )} + + ); +} diff --git a/frontend/src/components/scene/eventDeclaration/dragControlDeclaration.ts b/frontend/src/components/scene/eventDeclaration/dragControlDeclaration.ts new file mode 100644 index 0000000..43f8af4 --- /dev/null +++ b/frontend/src/components/scene/eventDeclaration/dragControlDeclaration.ts @@ -0,0 +1,80 @@ +import * as THREE from 'three'; +import { DragControls } from 'three/examples/jsm/controls/DragControls'; +import * as CONSTANTS from '../world/worldConstants'; +import DragPoint from '../geomentries/points/dragPoint'; + +import * as Types from "../world/worldTypes"; +import { updatePoint } from '../../../services/factoryBuilder/lines/updatePointApi'; +import { Socket } from 'socket.io-client'; + +export default async function addDragControl( + dragPointControls: Types.RefDragControl, + currentLayerPoint: Types.RefMeshArray, + state: Types.ThreeState, + floorPlanGroupPoint: Types.RefGroup, + floorPlanGroupLine: Types.RefGroup, + lines: Types.RefLines, + onlyFloorlines: Types.RefOnlyFloorLines, + socket: Socket +) { + + ////////// Dragging Point and also change the size to indicate during hover ////////// + + dragPointControls.current = new DragControls(currentLayerPoint.current, state.camera, state.gl.domElement); + dragPointControls.current.enabled = false; + + dragPointControls.current.addEventListener('drag', function (event) { + const object = event.object; + if (object.visible) { + (state.controls as any).enabled = false; + DragPoint(event as any, floorPlanGroupPoint, floorPlanGroupLine, state.scene, lines, onlyFloorlines) + } else { + (state.controls as any).enabled = true; + } + }); + + dragPointControls.current.addEventListener('dragstart', function (event) { + }); + + dragPointControls.current.addEventListener('dragend', async function (event) { + if (!dragPointControls.current) return; + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // await updatePoint( + // organization, + // { "x": event.object.position.x, "y": 0.01, "z": event.object.position.z }, + // event.object.uuid, + // ) + + //SOCKET + + const data = { + organization: organization, + position: { "x": event.object.position.x, "y": 0.01, "z": event.object.position.z }, + uuid: event.object.uuid, + socketId: socket.id + } + + socket.emit('v1:Line:update', data); + + if (state.controls) { + (state.controls as any).enabled = true; + } + }); + + dragPointControls.current.addEventListener('hoveron', function (event: any) { + if ((event.object as Types.Mesh).name === "point") { + event.object.material.uniforms.uInnerColor.value.set(event.object.userData.color) + } + }); + + dragPointControls.current.addEventListener('hoveroff', function (event: any) { + if ((event.object as Types.Mesh).name === "point") { + event.object.material.uniforms.uInnerColor.value.set(new THREE.Color(CONSTANTS.pointConfig.defaultInnerColor)) + } + }); + +} \ No newline at end of file diff --git a/frontend/src/components/scene/eventFunctions/handleContextMenu.ts b/frontend/src/components/scene/eventFunctions/handleContextMenu.ts new file mode 100644 index 0000000..ebf7edd --- /dev/null +++ b/frontend/src/components/scene/eventFunctions/handleContextMenu.ts @@ -0,0 +1,8 @@ +import * as Types from "../world/worldTypes"; + +export default function handleContextMenu( + menuVisible: Types.Boolean, + setMenuVisible: Types.BooleanState +): void { + // setMenuVisible(true) +} \ No newline at end of file diff --git a/frontend/src/components/scene/eventFunctions/handleMeshDown.ts b/frontend/src/components/scene/eventFunctions/handleMeshDown.ts new file mode 100644 index 0000000..e952412 --- /dev/null +++ b/frontend/src/components/scene/eventFunctions/handleMeshDown.ts @@ -0,0 +1,64 @@ +import * as THREE from 'three'; + +import * as Types from "../world/worldTypes"; + +function handleMeshDown( + event: Types.MeshEvent, + currentWallItem: Types.RefMesh, + setSelectedWallItem: Types.setSelectedWallItemSetState, + setSelectedItemsIndex: Types.setSelectedItemsIndexSetState, + wallItems: Types.wallItems, + toggleView: Types.Boolean +): void { + + ////////// To select which of the Wall item and CSG is selected to be dragged ////////// + + if (!toggleView) { + if (currentWallItem.current) { + currentWallItem.current.children.forEach((child) => { + if ((child as THREE.Mesh).isMesh && child.name !== "CSG_REF") { + const material = (child as THREE.Mesh).material; + if (Array.isArray(material)) { + material.forEach(mat => { + if (mat instanceof THREE.MeshStandardMaterial) { + mat.emissive = new THREE.Color("black"); + } + }); + } else if (material instanceof THREE.MeshStandardMaterial) { + material.emissive = new THREE.Color("black"); + } + } + }); + currentWallItem.current = null; + setSelectedWallItem(null); + setSelectedItemsIndex(null); + } + + if (event.intersections.length > 0) { + const clickedIndex = wallItems.findIndex((item) => item.model === event.intersections[0]?.object?.parent?.parent); + if (clickedIndex !== -1) { + setSelectedItemsIndex(clickedIndex); + const wallItemModel = wallItems[clickedIndex]?.model; + if (wallItemModel && wallItemModel.parent && wallItemModel.parent.parent) { + currentWallItem.current = (wallItemModel.parent.parent.children[0]?.children[1]?.children[0] as Types.Mesh) || null; + setSelectedWallItem(wallItemModel.parent); + // currentWallItem.current?.children.forEach((child) => { + // if ((child as THREE.Mesh).isMesh && child.name !== "CSG_REF") { + // const material = (child as THREE.Mesh).material; + // if (Array.isArray(material)) { + // material.forEach(mat => { + // if (mat instanceof THREE.MeshStandardMaterial) { + // mat.emissive = new THREE.Color("green"); + // } + // }); + // } else if (material instanceof THREE.MeshStandardMaterial) { + // material.emissive = new THREE.Color("green"); + // } + // } + // }); + } + } + } + } +} +export default handleMeshDown; diff --git a/frontend/src/components/scene/eventFunctions/handleMeshMissed.ts b/frontend/src/components/scene/eventFunctions/handleMeshMissed.ts new file mode 100644 index 0000000..4d8af8c --- /dev/null +++ b/frontend/src/components/scene/eventFunctions/handleMeshMissed.ts @@ -0,0 +1,34 @@ +import * as THREE from 'three'; +import * as Types from "../world/worldTypes"; + +function handleMeshMissed( + currentWallItem: Types.RefMesh, + setSelectedWallItem: Types.setSelectedWallItemSetState, + setSelectedItemsIndex: Types.setSelectedItemsIndexSetState +): void { + + ////////// If an item is selected and then clicked outside other than the selected object, this runs and removes the color of the selected object and sets setSelectedWallItem and setSelectedItemsIndex as null ////////// + + if (currentWallItem.current) { + currentWallItem.current.children.forEach((child) => { + if ((child as THREE.Mesh).isMesh && child.name !== "CSG_REF") { + const material = (child as THREE.Mesh).material; + + if (Array.isArray(material)) { + material.forEach(mat => { + if (mat instanceof THREE.MeshStandardMaterial) { + mat.emissive = new THREE.Color("black"); + } + }); + } else if (material instanceof THREE.MeshStandardMaterial) { + material.emissive = new THREE.Color("black"); + } + } + }); + currentWallItem.current = null; + setSelectedWallItem(null); + setSelectedItemsIndex(null); + } +} + +export default handleMeshMissed; diff --git a/frontend/src/components/scene/functions/deletableLineOrPoint.ts b/frontend/src/components/scene/functions/deletableLineOrPoint.ts new file mode 100644 index 0000000..644d3e7 --- /dev/null +++ b/frontend/src/components/scene/functions/deletableLineOrPoint.ts @@ -0,0 +1,88 @@ +import * as THREE from 'three'; +import * as CONSTANTS from '../world/worldConstants'; +import * as Types from "../world/worldTypes"; + +function DeletableLineorPoint( + state: Types.ThreeState, + plane: Types.RefMesh, + floorPlanGroupLine: Types.RefGroup, + floorPlanGroupPoint: Types.RefGroup, + hoveredDeletableLine: Types.RefMesh, + hoveredDeletablePoint: Types.RefMesh +): void { + + ////////// Altering the color of the hovered line or point during the deletion time ////////// + + if (!plane.current) return; + let intersects = state.raycaster.intersectObject(plane.current, true); + + let visibleIntersectLines; + if (floorPlanGroupLine.current) { visibleIntersectLines = state.raycaster?.intersectObjects(floorPlanGroupLine.current.children, true); } + const visibleIntersectLine = visibleIntersectLines?.find(intersect => intersect.object.visible) as THREE.Line | undefined || null; + + let visibleIntersectPoints; + if (floorPlanGroupPoint.current) { + visibleIntersectPoints = state.raycaster?.intersectObjects(floorPlanGroupPoint.current.children, true); + } + const visibleIntersectPoint = visibleIntersectPoints?.find(intersect => intersect.object.visible) as THREE.Mesh | undefined; + + function getLineColor(lineType: string | undefined): string { + switch (lineType) { + case CONSTANTS.lineConfig.wallName: return CONSTANTS.lineConfig.wallColor; + case CONSTANTS.lineConfig.floorName: return CONSTANTS.lineConfig.floorColor; + case CONSTANTS.lineConfig.aisleName: return CONSTANTS.lineConfig.aisleColor; + case CONSTANTS.lineConfig.zoneName: return CONSTANTS.lineConfig.zoneColor; + default: return CONSTANTS.lineConfig.defaultColor; + } + } + + if (intersects.length > 0) { + if (visibleIntersectPoint) { + if (hoveredDeletableLine.current) { + const lineType = hoveredDeletableLine.current.userData.linePoints[1]?.[3]; + const color = getLineColor(lineType); + (hoveredDeletableLine.current.material as THREE.MeshBasicMaterial).color = new THREE.Color(color); + hoveredDeletableLine.current = null; + } + + hoveredDeletablePoint.current = (visibleIntersectPoint as any).object; + (hoveredDeletablePoint.current as any).material.uniforms.uInnerColor.value.set(new THREE.Color("red")); + (hoveredDeletablePoint.current as any).material.uniforms.uColor.value.set(new THREE.Color("red")); + // (hoveredDeletablePoint.current as THREE.Mesh).scale.set(1.5, 1.5, 1.5); + } else if (hoveredDeletablePoint.current) { + (hoveredDeletablePoint.current as any).material.uniforms.uInnerColor.value.set(CONSTANTS.pointConfig.defaultInnerColor); + (hoveredDeletablePoint.current as any).material.uniforms.uColor.value.set((hoveredDeletablePoint.current as any).userData.color); + // hoveredDeletablePoint.current.scale.set(1, 1, 1); + hoveredDeletablePoint.current = null; + } + + if (visibleIntersectLine && !visibleIntersectPoint) { + if (hoveredDeletableLine.current) { + const lineType = hoveredDeletableLine.current.userData.linePoints[1]?.[3]; + const color = getLineColor(lineType); + (hoveredDeletableLine.current.material as THREE.MeshBasicMaterial).color = new THREE.Color(color); + hoveredDeletableLine.current = null; + } + + if (hoveredDeletablePoint.current) { + (hoveredDeletablePoint.current as any).material.uniforms.uInnerColor.value.set(CONSTANTS.pointConfig.defaultInnerColor); + (hoveredDeletablePoint.current as any).material.uniforms.uColor.value.set((hoveredDeletablePoint.current as any).userData.color); + // hoveredDeletablePoint.current.scale.set(1, 1, 1); + hoveredDeletablePoint.current = null; + } + + hoveredDeletableLine.current = (visibleIntersectLine as any).object; + if (hoveredDeletableLine.current) { + (hoveredDeletableLine.current.material as THREE.MeshBasicMaterial).color = new THREE.Color("red"); + } + } else if (hoveredDeletableLine.current) { + const lineType = hoveredDeletableLine.current.userData.linePoints[1]?.[3]; + const color = getLineColor(lineType); + (hoveredDeletableLine.current.material as THREE.MeshBasicMaterial).color = new THREE.Color(color); + hoveredDeletableLine.current = null; + } + } + +} + +export default DeletableLineorPoint; diff --git a/frontend/src/components/scene/functions/draw.ts b/frontend/src/components/scene/functions/draw.ts new file mode 100644 index 0000000..3dff707 --- /dev/null +++ b/frontend/src/components/scene/functions/draw.ts @@ -0,0 +1,99 @@ +import * as Types from "../world/worldTypes"; +import * as CONSTANTS from '../world/worldConstants'; +import createAndMoveReferenceLine from "../geomentries/lines/createAndMoveReferenceLine"; + +async function Draw( + state: Types.ThreeState, + plane: Types.RefMesh, + cursorPosition: Types.Vector3, + floorPlanGroupPoint: Types.RefGroup, + floorPlanGroupLine: Types.RefGroup, + snappedPoint: Types.RefVector3, + isSnapped: Types.RefBoolean, + isSnappedUUID: Types.RefString, + line: Types.RefLine, + lines: Types.RefLines, + ispreSnapped: Types.RefBoolean, + floorPlanGroup: Types.RefGroup, + ReferenceLineMesh: Types.RefMesh, + LineCreated: Types.RefBoolean, + setRefTextUpdate: Types.NumberIncrementState, + Tube: Types.RefTubeGeometry, + anglesnappedPoint: Types.RefVector3, + isAngleSnapped: Types.RefBoolean, + toolMode: Types.String, +): Promise { + + ////////// Snapping the cursor during the drawing time and also changing the color of the intersected lines ////////// + + if (!plane.current) return; + const intersects = state.raycaster.intersectObject(plane.current, true); + + if (intersects.length > 0) { + const intersectionPoint = intersects[0].point; + cursorPosition.copy(intersectionPoint); + const snapThreshold = 1; + + if (line.current.length === 0) { + for (const point of floorPlanGroupPoint.current.children) { + const pointType = point.userData.type; + + const canSnap = + ((toolMode === "Wall") && (pointType === CONSTANTS.lineConfig.wallName || pointType === CONSTANTS.lineConfig.floorName)) || + ((toolMode === "Floor") && (pointType === CONSTANTS.lineConfig.wallName || pointType === CONSTANTS.lineConfig.floorName)) || + ((toolMode === "Zone") && pointType === CONSTANTS.lineConfig.zoneName) || + ((toolMode === "Aisle") && pointType === CONSTANTS.lineConfig.aisleName);; + + if (canSnap && cursorPosition.distanceTo(point.position) < snapThreshold + 0.5 && point.visible) { + cursorPosition.copy(point.position); + snappedPoint.current = point.position; + ispreSnapped.current = true; + isSnapped.current = false; + isSnappedUUID.current = point.uuid; + break; + } else { + ispreSnapped.current = false; + } + } + } else if (line.current.length > 0 && line.current[0]) { + for (const point of floorPlanGroupPoint.current.children) { + const pointType = point.userData.type; + + let canSnap = + ((toolMode === "Wall") && (pointType === CONSTANTS.lineConfig.wallName || pointType === CONSTANTS.lineConfig.floorName)) || + ((toolMode === "Floor") && (pointType === CONSTANTS.lineConfig.wallName || pointType === CONSTANTS.lineConfig.floorName)) || + ((toolMode === "Zone") && pointType === CONSTANTS.lineConfig.zoneName) || + ((toolMode === "Aisle") && pointType === CONSTANTS.lineConfig.aisleName); + + if (canSnap && cursorPosition.distanceTo(point.position) < snapThreshold && point.visible) { + cursorPosition.copy(point.position); + snappedPoint.current = point.position; + isSnapped.current = true; + ispreSnapped.current = false; + isSnappedUUID.current = point.uuid; + break; + } else { + isSnapped.current = false; + } + } + + createAndMoveReferenceLine( + line.current[0][0], + cursorPosition, + isSnapped, + ispreSnapped, + line, + setRefTextUpdate, + floorPlanGroup, + ReferenceLineMesh, + LineCreated, + Tube, + anglesnappedPoint, + isAngleSnapped + ); + } + } + +} + +export default Draw; \ No newline at end of file diff --git a/frontend/src/components/scene/geomentries/aisles/addAilseToScene.ts b/frontend/src/components/scene/geomentries/aisles/addAilseToScene.ts new file mode 100644 index 0000000..5ff54ca --- /dev/null +++ b/frontend/src/components/scene/geomentries/aisles/addAilseToScene.ts @@ -0,0 +1,56 @@ +import * as THREE from 'three'; +import * as Types from '../../world/worldTypes'; +import * as CONSTANTS from '../../world/worldConstants'; + +export default async function addAisleToScene( + aisle: Types.Line, + floorGroupAisle: Types.RefGroup, +): Promise { + if (aisle.length >= 2 && aisle[0] && aisle[1]) { + const start: Types.Vector3 = aisle[0][0]; + const end: Types.Vector3 = aisle[1][0]; + + const direction = new THREE.Vector3( + end.x - start.x, + end.y - start.y, + end.z - start.z + ).normalize(); + + const perp = new THREE.Vector3(-direction.z, 0, direction.x).normalize(); + const offsetDistance = CONSTANTS.aisleConfig.width; + + const leftStart = new THREE.Vector3().copy(start).addScaledVector(perp, offsetDistance); + const rightStart = new THREE.Vector3().copy(start).addScaledVector(perp, -offsetDistance); + const leftEnd = new THREE.Vector3().copy(end).addScaledVector(perp, offsetDistance); + const rightEnd = new THREE.Vector3().copy(end).addScaledVector(perp, -offsetDistance); + + const stripShape = new THREE.Shape(); + stripShape.moveTo(leftStart.x, leftStart.z); + stripShape.lineTo(leftEnd.x, leftEnd.z); + stripShape.lineTo(rightEnd.x, rightEnd.z); + stripShape.lineTo(rightStart.x, rightStart.z); + stripShape.lineTo(leftStart.x, leftStart.z); + + const extrudeSettings = { + depth: CONSTANTS.aisleConfig.height, + bevelEnabled: false, + }; + + const stripGeometry = new THREE.ExtrudeGeometry(stripShape, extrudeSettings); + const stripMaterial = new THREE.MeshStandardMaterial({ + color: CONSTANTS.aisleConfig.defaultColor, + polygonOffset: true, + polygonOffsetFactor: -1, + polygonOffsetUnits: -1, + }); + + const stripMesh = new THREE.Mesh(stripGeometry, stripMaterial); + stripMesh.receiveShadow = true; + stripMesh.castShadow = true; + + stripMesh.position.y = (aisle[0][2] - 1) * CONSTANTS.wallConfig.height + 0.01; + stripMesh.rotateX(Math.PI / 2); + + floorGroupAisle.current.add(stripMesh); + } +} diff --git a/frontend/src/components/scene/geomentries/aisles/loadAisles.ts b/frontend/src/components/scene/geomentries/aisles/loadAisles.ts new file mode 100644 index 0000000..ad976b3 --- /dev/null +++ b/frontend/src/components/scene/geomentries/aisles/loadAisles.ts @@ -0,0 +1,19 @@ +import * as Types from '../../world/worldTypes'; +import addAisleToScene from './addAilseToScene'; +import * as CONSTANTS from '../../world/worldConstants'; + +export default async function loadAisles( + lines: Types.RefLines, + floorGroupAisle: Types.RefGroup +) { + // console.log('lines: ', lines.current[0][0][0]); + if (!floorGroupAisle.current) return + floorGroupAisle.current.children = []; + const aisles = lines.current.filter((line) => line[0][3] && line[1][3] === CONSTANTS.lineConfig.aisleName); + + if (aisles.length > 0) { + aisles.forEach((aisle: Types.Line) => { + addAisleToScene(aisle, floorGroupAisle) + }) + } +} \ No newline at end of file diff --git a/frontend/src/components/scene/geomentries/assets/addAssetModel.ts b/frontend/src/components/scene/geomentries/assets/addAssetModel.ts new file mode 100644 index 0000000..eef3c40 --- /dev/null +++ b/frontend/src/components/scene/geomentries/assets/addAssetModel.ts @@ -0,0 +1,186 @@ +import * as THREE from 'three'; +import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; +import gsap from 'gsap'; +import { toast } from 'react-toastify'; +import TempLoader from './tempLoader'; +import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'; +import * as Types from "../../world/worldTypes"; +import { retrieveGLTF, storeGLTF } from '../../indexDB/idbUtils'; +import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi'; +import { Socket } from 'socket.io-client'; +import * as CONSTANTS from '../../world/worldConstants'; + +async function addAssetModel( + raycaster: THREE.Raycaster, + camera: THREE.Camera, + pointer: THREE.Vector2, + floorGroup: Types.RefGroup, + setFloorItems: Types.setFloorItemSetState, + itemsGroup: Types.RefGroup, + isTempLoader: Types.RefBoolean, + tempLoader: Types.RefMesh, + socket: Socket, + selectedItem: any, + setSelectedItem: any, + plane: Types.RefMesh, +): Promise { + + ////////// Load Floor GLtf's and set the positions, rotation, type etc. in state and store in localstorage ////////// + + let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`; + + try { + isTempLoader.current = true; + const loader = new GLTFLoader(); + const dracoLoader = new DRACOLoader(); + + dracoLoader.setDecoderPath('https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/'); + loader.setDRACOLoader(dracoLoader); + + raycaster.setFromCamera(pointer, camera); + const floorIntersections = raycaster.intersectObjects(floorGroup.current.children, true); + const intersectedFloor = floorIntersections.find(intersect => intersect.object.name.includes("Floor")); + + const planeIntersections = raycaster.intersectObject(plane.current!, true); + const intersectedPlane = planeIntersections[0]; + + let intersectPoint: THREE.Vector3 | null = null; + + if (intersectedFloor && intersectedPlane) { + intersectPoint = intersectedFloor.distance < intersectedPlane.distance ? (new THREE.Vector3(intersectedFloor.point.x, Math.round(intersectedFloor.point.y), intersectedFloor.point.z)) : (new THREE.Vector3(intersectedPlane.point.x, 0, intersectedPlane.point.z)); + } else if (intersectedFloor) { + intersectPoint = new THREE.Vector3(intersectedFloor.point.x, Math.round(intersectedFloor.point.y), intersectedFloor.point.z); + } else if (intersectedPlane) { + intersectPoint = new THREE.Vector3(intersectedPlane.point.x, 0, intersectedPlane.point.z); + } + + if (intersectPoint) { + if (intersectPoint.y < 0) { + intersectPoint = new THREE.Vector3(intersectPoint.x, 0, intersectPoint.z); + } + const cachedModel = THREE.Cache.get(selectedItem.id); + if (cachedModel) { + // console.log(`[Cache] Fetching ${selectedItem.name}`); + handleModelLoad(cachedModel, intersectPoint!, selectedItem, itemsGroup, tempLoader, isTempLoader, setFloorItems, socket); + return; + } else { + const cachedModelBlob = await retrieveGLTF(selectedItem.id); + + if (cachedModelBlob) { + // console.log(`Added ${selectedItem.name} from indexDB`); + + const blobUrl = URL.createObjectURL(cachedModelBlob); + loader.load(blobUrl, (gltf) => { + URL.revokeObjectURL(blobUrl); + THREE.Cache.remove(blobUrl); + THREE.Cache.add(selectedItem.id, gltf); + handleModelLoad(gltf, intersectPoint!, selectedItem, itemsGroup, tempLoader, isTempLoader, setFloorItems, socket); + }, + () => { + TempLoader(intersectPoint!, isTempLoader, tempLoader, itemsGroup); + }); + } else { + // console.log(`Added ${selectedItem.name} from Backend`); + + loader.load(`${url_Backend_dwinzo}/api/v1/AssetFile/${selectedItem.id}`, async (gltf) => { + const modelBlob = await fetch(`${url_Backend_dwinzo}/api/v1/AssetFile/${selectedItem.id}`).then((res) => res.blob()); + await storeGLTF(selectedItem.id, modelBlob); + THREE.Cache.add(selectedItem.id, gltf); + await handleModelLoad(gltf, intersectPoint!, selectedItem, itemsGroup, tempLoader, isTempLoader, setFloorItems, socket); + }, + () => { + TempLoader(intersectPoint!, isTempLoader, tempLoader, itemsGroup); + }); + } + } + } + } catch (error) { + console.error('Error fetching asset model:', error); + } finally { + setSelectedItem({}); + } +} + +async function handleModelLoad( + gltf: any, + intersectPoint: THREE.Vector3, + selectedItem: any, + itemsGroup: Types.RefGroup, + tempLoader: Types.RefMesh, + isTempLoader: Types.RefBoolean, + setFloorItems: Types.setFloorItemSetState, + socket: Socket +) { + const model = gltf.scene.clone(); + model.userData = { name: selectedItem.name, modelId: selectedItem.id }; + model.position.set(intersectPoint!.x, 3 + intersectPoint!.y, intersectPoint!.z); + model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap); + + model.traverse((child: any) => { + if (child) { + child.castShadow = true; + child.receiveShadow = true; + } + }); + + itemsGroup.current.add(model); + if (tempLoader.current) { + (tempLoader.current.material).dispose(); + (tempLoader.current.geometry).dispose(); + itemsGroup.current.remove(tempLoader.current); + tempLoader.current = undefined; + } + + const newFloorItem: Types.FloorItemType = { + modeluuid: model.uuid, + modelname: selectedItem.name, + modelfileID: selectedItem.id, + position: [intersectPoint!.x, intersectPoint!.y, intersectPoint!.z], + rotation: { x: model.rotation.x, y: model.rotation.y, z: model.rotation.z, }, + isLocked: false, + isVisible: true + }; + + setFloorItems((prevItems) => { + const updatedItems = [...(prevItems || []), newFloorItem]; + localStorage.setItem("FloorItems", JSON.stringify(updatedItems)); + return updatedItems; + }); + + const email = localStorage.getItem("email"); + const organization = email ? email.split("@")[1].split(".")[0] : "default"; + + //REST + + // await setFloorItemApi( + // organization, + // newFloorItem.modeluuid, + // newFloorItem.modelname, + // newFloorItem.position, + // { "x": model.rotation.x, "y": model.rotation.y, "z": model.rotation.z }, + // newFloorItem.modelfileID!, + // false, + // true, + // ); + + //SOCKET + + const data = { + organization, + modeluuid: newFloorItem.modeluuid, + modelname: newFloorItem.modelname, + modelfileID: newFloorItem.modelfileID, + position: newFloorItem.position, + rotation: { x: model.rotation.x, y: model.rotation.y, z: model.rotation.z }, + isLocked: false, + isVisible: true, + socketId: socket.id, + }; + + socket.emit("v1:FloorItems:set", data); + + gsap.to(model.position, { y: newFloorItem.position[1], duration: 1.5, ease: "power2.out" }); + gsap.to(model.scale, { x: 1, y: 1, z: 1, duration: 1.5, ease: "power2.out", onComplete: () => { toast.success("Model Added!"); } }); +} + +export default addAssetModel; diff --git a/frontend/src/components/scene/geomentries/assets/assetManager.ts b/frontend/src/components/scene/geomentries/assets/assetManager.ts new file mode 100644 index 0000000..f9d5aa9 --- /dev/null +++ b/frontend/src/components/scene/geomentries/assets/assetManager.ts @@ -0,0 +1,153 @@ +import * as THREE from "three"; +import gsap from "gsap"; +import * as Types from "../../world/worldTypes"; +import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; +import { initializeDB, retrieveGLTF, storeGLTF } from "../../indexDB/idbUtils"; +import * as CONSTANTS from '../../world/worldConstants'; +import { toast } from 'react-toastify'; + +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`; +let currentTaskId = 0; // Track the active task +let activePromises = new Map(); // Map to track task progress + +export default async function assetManager( + data: any, + itemsGroup: Types.RefGroup, + loader: GLTFLoader, +) { + const taskId = ++currentTaskId; // Increment taskId for each call + activePromises.set(taskId, true); // Mark task as active + + // console.log("Received message from worker:", data); + + if (data.toRemove.length > 0) { + data.toRemove.forEach((uuid: string) => { + const item = itemsGroup.current.getObjectByProperty("uuid", uuid); + if (item) { + // Traverse and dispose of resources + // item.traverse((child: THREE.Object3D) => { + // if (child instanceof THREE.Mesh) { + // if (child.geometry) child.geometry.dispose(); + // if (Array.isArray(child.material)) { + // child.material.forEach((material) => { + // if (material.map) material.map.dispose(); + // material.dispose(); + // }); + // } else if (child.material) { + // if (child.material.map) child.material.map.dispose(); + // child.material.dispose(); + // } + // } + // }); + + // Remove the object from the scene + itemsGroup.current.remove(item); + } + }); + } + + if (data.toAdd.length > 0) { + await initializeDB(); + + for (const item of data.toAdd) { + if (!activePromises.get(taskId)) return; // Stop processing if task is canceled + + await new Promise(async (resolve) => { + const modelUrl = `${url_Backend_dwinzo}/api/v1/AssetFile/${item.modelfileID!}`; + + // Check Three.js Cache + const cachedModel = THREE.Cache.get(item.modelfileID!); + if (cachedModel) { + // console.log(`[Cache] Fetching ${item.modelname}`); + processLoadedModel(cachedModel.scene.clone(), item, itemsGroup, resolve); + return; + } + + // Check IndexedDB + const indexedDBModel = await retrieveGLTF(item.modelfileID!); + if (indexedDBModel) { + // console.log(`[IndexedDB] Fetching ${item.modelname}`); + const blobUrl = URL.createObjectURL(indexedDBModel); + loader.load( + blobUrl, + (gltf) => { + URL.revokeObjectURL(blobUrl); + THREE.Cache.remove(blobUrl); + THREE.Cache.add(item.modelfileID!, gltf); // Add to cache + processLoadedModel(gltf.scene.clone(), item, itemsGroup, resolve); + }, + undefined, + (error) => { + toast.error(`[IndexedDB] Error loading ${item.modelname}:`); + resolve(); + } + ); + return; + } + + // Fetch from Backend + // console.log(`[Backend] Fetching ${item.modelname}`); + loader.load( + modelUrl, + async (gltf) => { + const modelBlob = await fetch(modelUrl).then((res) => res.blob()); + await storeGLTF(item.modelfileID!, modelBlob); // Store in IndexedDB + THREE.Cache.add(item.modelfileID!, gltf); // Add to cache + processLoadedModel(gltf.scene.clone(), item, itemsGroup, resolve); + }, + undefined, + (error) => { + toast.error(`[Backend] Error loading ${item.modelname}:`); + resolve(); + } + ); + }); + } + + function processLoadedModel( + gltf: any, + item: Types.FloorItemType, + itemsGroup: Types.RefGroup, + resolve: () => void + ) { + if (!activePromises.get(taskId)) return; // Stop processing if task is canceled + + const existingModel = itemsGroup.current.getObjectByProperty("uuid", item.modeluuid); + if (existingModel) { + // console.log(`Model ${item.modelname} already exists in the scene.`); + resolve(); + return; + } + + const model = gltf; + model.uuid = item.modeluuid; + model.userData = { name: item.modelname, modelId: item.modelfileID }; + model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap); + model.position.set(...item.position); + model.rotation.set(item.rotation.x, item.rotation.y, item.rotation.z); + + model.traverse((child: any) => { + if (child.isMesh) { + // Clone the material to ensure changes are independent + // child.material = child.material.clone(); + + child.castShadow = true; + child.receiveShadow = true; + } + }); + + + itemsGroup?.current?.add(model); + + gsap.to(model.position, { y: item.position[1], duration: 1.5, ease: "power2.out" }); + gsap.to(model.scale, { x: 1, y: 1, z: 1, duration: 0.5, ease: "power2.out", onStart: resolve, }); + } + } + + activePromises.delete(taskId); // Mark task as complete +} + +// Cancel ongoing task when new call arrives +export function cancelOngoingTasks() { + activePromises.clear(); // Clear all ongoing tasks +} diff --git a/frontend/src/components/scene/geomentries/assets/assetVisibility.ts b/frontend/src/components/scene/geomentries/assets/assetVisibility.ts new file mode 100644 index 0000000..db0aa19 --- /dev/null +++ b/frontend/src/components/scene/geomentries/assets/assetVisibility.ts @@ -0,0 +1,25 @@ +import * as Types from "../../world/worldTypes"; + +let lastUpdateTime = 0; + +export default function assetVisibility( + itemsGroup: Types.RefGroup, + cameraPosition: Types.Vector3, + renderDistance: Types.Number, + throttleTime = 100 +): void { + const now = performance.now(); + if (now - lastUpdateTime < throttleTime) return; + lastUpdateTime = now; + + if (!itemsGroup?.current || !cameraPosition) return; + + itemsGroup.current.children.forEach((child) => { + const Distance = cameraPosition.distanceTo(child.position); + if (Distance <= renderDistance) { + child.visible = true; + } else { + child.visible = false; + } + }); +} diff --git a/frontend/src/components/scene/geomentries/assets/deletableHoveredFloorItems.ts b/frontend/src/components/scene/geomentries/assets/deletableHoveredFloorItems.ts new file mode 100644 index 0000000..866c37d --- /dev/null +++ b/frontend/src/components/scene/geomentries/assets/deletableHoveredFloorItems.ts @@ -0,0 +1,43 @@ +import * as THREE from 'three'; + +import * as Types from "../../world/worldTypes"; + +function DeletableHoveredFloorItems( + state: Types.ThreeState, + itemsGroup: Types.RefGroup, + hoveredDeletableFloorItem: Types.RefMesh, + setDeletableFloorItem: any +): void { + + ////////// Altering the color of the hovered GLTF item during the Deletion time ////////// + + state.raycaster.setFromCamera(state.pointer, state.camera); + const intersects = state.raycaster.intersectObjects(itemsGroup.current.children, true); + + if (intersects.length > 0) { + if (intersects[0].object.name === "Pole") { + return; + } + if (hoveredDeletableFloorItem.current) { + hoveredDeletableFloorItem.current = undefined; + setDeletableFloorItem(null); + } + let currentObject = intersects[0].object; + + while (currentObject) { + if (currentObject.name === "Scene") { + hoveredDeletableFloorItem.current = currentObject as THREE.Mesh; + setDeletableFloorItem(currentObject); + break; + } + currentObject = currentObject.parent as THREE.Object3D; + } + } else { + if (hoveredDeletableFloorItem.current) { + hoveredDeletableFloorItem.current = undefined; + setDeletableFloorItem(null); + } + } +} + +export default DeletableHoveredFloorItems; diff --git a/frontend/src/components/scene/geomentries/assets/deleteFloorItems.ts b/frontend/src/components/scene/geomentries/assets/deleteFloorItems.ts new file mode 100644 index 0000000..53d488f --- /dev/null +++ b/frontend/src/components/scene/geomentries/assets/deleteFloorItems.ts @@ -0,0 +1,82 @@ +import { toast } from 'react-toastify'; +import * as THREE from 'three'; + +import * as Types from "../../world/worldTypes"; +import { getFloorItems } from '../../../../services/factoryBuilder/assest/floorAsset/getFloorItemsApi'; +import { deleteFloorItem } from '../../../../services/factoryBuilder/assest/floorAsset/deleteFloorItemApi'; +import { Socket } from 'socket.io-client'; + +async function DeleteFloorItems( + itemsGroup: Types.RefGroup, + hoveredDeletableFloorItem: Types.RefMesh, + setFloorItems: Types.setFloorItemSetState, + socket: Socket +): Promise { + + ////////// Deleting the hovered Floor GLTF from the scene (itemsGroup.current) and from the floorItems and also update it in the localstorage ////////// + + if (hoveredDeletableFloorItem.current) { + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + const items = await getFloorItems(organization); + const removedItem = items.find( + (item: { modeluuid: string }) => item.modeluuid === hoveredDeletableFloorItem.current?.uuid + ); + + if (!removedItem) { + return + } + + //REST + + // const response = await deleteFloorItem(organization, removedItem.modeluuid, removedItem.modelname); + + //SOCKET + + const data = { + organization: organization, + modeluuid: removedItem.modeluuid, + modelname: removedItem.modelname, + socketId: socket.id + } + + const response = socket.emit('v1:FloorItems:delete', data) + + if (response) { + const updatedItems = items.filter( + (item: { modeluuid: string }) => item.modeluuid !== hoveredDeletableFloorItem.current?.uuid + ); + + const storedItems = JSON.parse(localStorage.getItem("FloorItems") || '[]'); + const updatedStoredItems = storedItems.filter((item: { modeluuid: string }) => item.modeluuid !== hoveredDeletableFloorItem.current?.uuid); + localStorage.setItem("FloorItems", JSON.stringify(updatedStoredItems)); + + if (hoveredDeletableFloorItem.current) { + // Traverse and dispose of resources + hoveredDeletableFloorItem.current.traverse((child: THREE.Object3D) => { + if (child instanceof THREE.Mesh) { + if (child.geometry) child.geometry.dispose(); + if (Array.isArray(child.material)) { + child.material.forEach((material) => { + if (material.map) material.map.dispose(); + material.dispose(); + }); + } else if (child.material) { + if (child.material.map) child.material.map.dispose(); + child.material.dispose(); + } + } + }); + + // Remove the object from the scene + itemsGroup.current.remove(hoveredDeletableFloorItem.current); + } + setFloorItems(updatedItems); + toast.success("Model Removed!"); + } + } +} + +export default DeleteFloorItems; diff --git a/frontend/src/components/scene/geomentries/assets/tempLoader.ts b/frontend/src/components/scene/geomentries/assets/tempLoader.ts new file mode 100644 index 0000000..db0f976 --- /dev/null +++ b/frontend/src/components/scene/geomentries/assets/tempLoader.ts @@ -0,0 +1,29 @@ +import * as THREE from 'three'; + +import * as Types from "../../world/worldTypes"; + +function TempLoader( + intersectPoint: Types.Vector3, + isTempLoader: Types.RefBoolean, + tempLoader: Types.RefMesh, + itemsGroup: Types.RefGroup +): void { + + ////////// Temporary Loader that indicates the gltf is being loaded ////////// + + ////////// Bug: Can't Load More than one TempLoader if done, it won't leave the scene ////////// + + if (tempLoader.current) { + itemsGroup.current.remove(tempLoader.current); + } + if (isTempLoader.current) { + const cubeGeometry = new THREE.BoxGeometry(1, 1, 1); + const cubeMaterial = new THREE.MeshBasicMaterial({ color: "white" }); + tempLoader.current = new THREE.Mesh(cubeGeometry, cubeMaterial); + tempLoader.current.position.set(intersectPoint.x, 0.5 + intersectPoint.y, intersectPoint.z); + itemsGroup.current.add(tempLoader.current); + isTempLoader.current = false; + } +} + +export default TempLoader; diff --git a/frontend/src/components/scene/geomentries/floors/addFloorToScene.ts b/frontend/src/components/scene/geomentries/floors/addFloorToScene.ts new file mode 100644 index 0000000..57e5816 --- /dev/null +++ b/frontend/src/components/scene/geomentries/floors/addFloorToScene.ts @@ -0,0 +1,64 @@ +import * as THREE from 'three'; +import * as Types from "../../world/worldTypes"; +import * as CONSTANTS from "../../world/worldConstants"; + +import texturePath from "../../../../assets/textures/floor/concreteFloorWorn001Diff2k.jpg"; +import normalPath from "../../../../assets/textures/floor/concreteFloorWorn001NorGl2k.jpg"; + +// Cache for materials +const materialCache = new Map(); + +export default function addFloorToScene( + shape: THREE.Shape, + layer: number, + floorGroup: Types.RefGroup, + userData: any, +) { + const textureLoader = new THREE.TextureLoader(); + + const textureScale = CONSTANTS.floorConfig.textureScale; + + const materialKey = `floorMaterial_${textureScale}`; + + let material: THREE.Material; + + if (materialCache.has(materialKey)) { + material = materialCache.get(materialKey) as THREE.Material; + } else { + const floorTexture = textureLoader.load(texturePath); + const normalMap = textureLoader.load(normalPath); + + floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping; + floorTexture.repeat.set(textureScale, textureScale); + floorTexture.colorSpace = THREE.SRGBColorSpace; + + normalMap.wrapS = normalMap.wrapT = THREE.RepeatWrapping; + normalMap.repeat.set(textureScale, textureScale); + + material = new THREE.MeshStandardMaterial({ + map: floorTexture, + normalMap: normalMap, + side: THREE.DoubleSide, + }); + + materialCache.set(materialKey, material); + } + + const extrudeSettings = { + depth: CONSTANTS.floorConfig.height, + bevelEnabled: false, + }; + + const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings); + const mesh = new THREE.Mesh(geometry, material); + + mesh.receiveShadow = true; + mesh.position.y = layer; + mesh.rotateX(Math.PI / 2); + mesh.name = `Floor_Layer_${layer}`; + + // Store UUIDs for debugging or future processing + mesh.userData.uuids = userData; + + floorGroup.current.add(mesh); +} diff --git a/frontend/src/components/scene/geomentries/floors/drawOnlyFloor.ts b/frontend/src/components/scene/geomentries/floors/drawOnlyFloor.ts new file mode 100644 index 0000000..7b5cdaf --- /dev/null +++ b/frontend/src/components/scene/geomentries/floors/drawOnlyFloor.ts @@ -0,0 +1,179 @@ +import * as THREE from 'three'; + +import * as Types from "../../world/worldTypes"; +import * as CONSTANTS from '../../world/worldConstants'; + +import addPointToScene from '../points/addPointToScene'; +import addLineToScene from '../lines/addLineToScene'; +import splitLine from '../lines/splitLine'; +import removeReferenceLine from '../lines/removeReferenceLine'; +import getClosestIntersection from '../lines/getClosestIntersection'; +import arrayLineToObject from '../lines/lineConvertions/arrayLineToObject'; +import { setLine } from '../../../../services/factoryBuilder/lines/setLineApi'; +import { Socket } from 'socket.io-client'; + +async function drawOnlyFloor( + raycaster: THREE.Raycaster, + state: Types.ThreeState, + camera: THREE.Camera, + plane: Types.RefMesh, + floorPlanGroupPoint: Types.RefGroup, + snappedPoint: Types.RefVector3, + isSnapped: Types.RefBoolean, + isSnappedUUID: Types.RefString, + line: Types.RefLine, + ispreSnapped: Types.RefBoolean, + anglesnappedPoint: Types.RefVector3, + isAngleSnapped: Types.RefBoolean, + onlyFloorline: Types.RefOnlyFloorLine, + onlyFloorlines: Types.RefOnlyFloorLines, + lines: Types.RefLines, + floorPlanGroupLine: Types.RefGroup, + floorPlanGroup: Types.RefGroup, + ReferenceLineMesh: Types.RefMesh, + LineCreated: Types.RefBoolean, + currentLayerPoint: Types.RefMeshArray, + dragPointControls: Types.RefDragControl, + setNewLines: any, + setDeletedLines: any, + activeLayer: Types.Number, + socket: Socket +): Promise { + + ////////// Creating lines Based on the positions clicked ////////// + + if (!plane.current) return + const intersects = raycaster.intersectObject(plane.current, true); + const intersectsLines = raycaster.intersectObjects(floorPlanGroupLine.current.children, true); + const intersectsPoint = raycaster.intersectObjects(floorPlanGroupPoint.current.children, true); + const VisibleintersectsPoint = intersectsPoint.find(intersect => intersect.object.visible); + const visibleIntersect = intersectsLines.find(intersect => intersect.object.visible && intersect.object.name !== CONSTANTS.lineConfig.referenceName); + + if ((intersectsPoint.length === 0 || VisibleintersectsPoint === undefined) && intersectsLines.length > 0 && !isSnapped.current && !ispreSnapped.current) { + + ////////// Clicked on a preexisting Line ////////// + + if (visibleIntersect && (intersectsLines[0].object.userData.linePoints[0][3] === CONSTANTS.lineConfig.floorName || intersectsLines[0].object.userData.linePoints[0][3] === CONSTANTS.lineConfig.wallName)) { + let pointColor, lineColor; + if (intersectsLines[0].object.userData.linePoints[0][3] === CONSTANTS.lineConfig.wallName) { + pointColor = CONSTANTS.pointConfig.wallOuterColor; + lineColor = CONSTANTS.lineConfig.wallColor; + } else { + pointColor = CONSTANTS.pointConfig.floorOuterColor; + lineColor = CONSTANTS.lineConfig.floorColor; + } + let IntersectsPoint = new THREE.Vector3(intersects[0].point.x, 0.01, intersects[0].point.z); + if (isAngleSnapped.current && line.current.length > 0 && anglesnappedPoint.current) { + IntersectsPoint = anglesnappedPoint.current; + } + if (visibleIntersect.object instanceof THREE.Mesh) { + const ThroughPoint = (visibleIntersect.object.geometry.parameters.path).getPoints(CONSTANTS.lineConfig.lineIntersectionPoints); + let intersectionPoint = getClosestIntersection(ThroughPoint, IntersectsPoint); + + if (intersectionPoint) { + + const newLines = splitLine(visibleIntersect, intersectionPoint, currentLayerPoint, floorPlanGroupPoint, dragPointControls, isSnappedUUID, lines, setDeletedLines, floorPlanGroupLine, socket, pointColor, lineColor, intersectsLines[0].object.userData.linePoints[0][3]); + setNewLines([newLines[0], newLines[1]]); + + (line.current as Types.Line).push([new THREE.Vector3(intersectionPoint.x, 0.01, intersectionPoint.z), isSnappedUUID.current!, activeLayer, CONSTANTS.lineConfig.floorName]); + + if (line.current.length >= 2 && line.current[0] && line.current[1]) { + lines.current.push(line.current as Types.Line); + const data = arrayLineToObject(line.current as Types.Line); + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // setLine(organization, data.layer!, data.line!, data.type!); + + //SOCKET + + const input = { + organization: organization, + layer: data.layer, + line: data.line, + type: data.type, + socketId: socket.id + } + + socket.emit('v1:Line:create', input); + + setNewLines([newLines[0], newLines[1], line.current]); + onlyFloorline.current.push(line.current as Types.Line); + onlyFloorlines.current.push(onlyFloorline.current); + onlyFloorline.current = []; + + addLineToScene(line.current[0][0], line.current[1][0], CONSTANTS.lineConfig.floorColor, line.current, floorPlanGroupLine); + + removeReferenceLine(floorPlanGroup, ReferenceLineMesh, LineCreated, line); + } + return; + } + } + } + } + if (intersects.length > 0 && intersectsLines.length === 0) { + + ////////// Clicked on an empty place or a point ////////// + + let intersectionPoint = intersects[0].point; + + if (isAngleSnapped.current && line.current.length > 0 && anglesnappedPoint.current) { + intersectionPoint = anglesnappedPoint.current; + } + if (isSnapped.current && line.current.length > 0 && snappedPoint.current) { + intersectionPoint = snappedPoint.current; + } + if (ispreSnapped.current && snappedPoint.current) { + intersectionPoint = snappedPoint.current; + } + + if (!isSnapped.current && !ispreSnapped.current) { + addPointToScene(intersectionPoint, CONSTANTS.pointConfig.floorOuterColor, currentLayerPoint, floorPlanGroupPoint, dragPointControls, isSnappedUUID, CONSTANTS.lineConfig.floorName); + } else { + ispreSnapped.current = false; + isSnapped.current = false; + } + + (line.current as Types.Line).push([new THREE.Vector3(intersectionPoint.x, 0.01, intersectionPoint.z), isSnappedUUID.current!, activeLayer, CONSTANTS.lineConfig.floorName]); + + if (line.current.length >= 2 && line.current[0] && line.current[1]) { + onlyFloorline.current.push(line.current as Types.Line); + lines.current.push(line.current as Types.Line); + const data = arrayLineToObject(line.current as Types.Line); + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // setLine(organization, data.layer!, data.line!, data.type!); + + //SOCKET + + const input = { + organization: organization, + layer: data.layer, + line: data.line, + type: data.type, + socketId: socket.id + } + + socket.emit('v1:Line:create', input); + + setNewLines([line.current]); + addLineToScene(line.current[0][0], line.current[1][0], CONSTANTS.lineConfig.floorColor, line.current, floorPlanGroupLine); + const lastPoint = line.current[line.current.length - 1]; + line.current = [lastPoint]; + } + if (isSnapped.current) { ////////// Add this to stop the drawing mode after snapping ////////// + removeReferenceLine(floorPlanGroup, ReferenceLineMesh, LineCreated, line); + onlyFloorlines.current.push(onlyFloorline.current); + onlyFloorline.current = []; + } + } +} + +export default drawOnlyFloor; \ No newline at end of file diff --git a/frontend/src/components/scene/geomentries/floors/loadFloor.ts b/frontend/src/components/scene/geomentries/floors/loadFloor.ts new file mode 100644 index 0000000..b8549e1 --- /dev/null +++ b/frontend/src/components/scene/geomentries/floors/loadFloor.ts @@ -0,0 +1,50 @@ +import * as THREE from 'three'; +import * as CONSTANTS from '../../world/worldConstants'; +import addRoofToScene from '../roofs/addRoofToScene'; + +import * as Types from "../../world/worldTypes"; +import loadOnlyFloors from './loadOnlyFloors'; +import addFloorToScene from './addFloorToScene'; +import getRoomsFromLines from '../lines/getRoomsFromLines'; + +async function loadFloor( + lines: Types.RefLines, + floorGroup: Types.RefGroup, +): Promise { + + if (!floorGroup.current) return; + + floorGroup.current.children = []; + + if (lines.current.length > 2) { + const linesByLayer = lines.current.reduce((acc: { [key: number]: any[] }, pair) => { + const layer = pair[0][2]; + if (!acc[layer]) acc[layer] = []; + acc[layer].push(pair); + return acc; + }, {}); + + for (const layer in linesByLayer) { + // Only Floor Polygons + loadOnlyFloors(floorGroup, linesByLayer, layer); + + const rooms: Types.Rooms = await getRoomsFromLines({ current: linesByLayer[layer] }); + + rooms.forEach(({ coordinates: room, layer }) => { + const userData = room.map(point => point.uuid); + const shape = new THREE.Shape(); + shape.moveTo(room[0].position.x, room[0].position.z); + room.forEach(point => shape.lineTo(point.position.x, point.position.z)); + shape.closePath(); + + // Floor Polygons + addFloorToScene(shape, (layer - 1) * CONSTANTS.wallConfig.height, floorGroup, userData); + + // Roof Polygons + addRoofToScene(shape, (layer - 1) * CONSTANTS.wallConfig.height, userData, floorGroup); + }); + } + } +} + +export default loadFloor; diff --git a/frontend/src/components/scene/geomentries/floors/loadOnlyFloors.ts b/frontend/src/components/scene/geomentries/floors/loadOnlyFloors.ts new file mode 100644 index 0000000..f458cb5 --- /dev/null +++ b/frontend/src/components/scene/geomentries/floors/loadOnlyFloors.ts @@ -0,0 +1,183 @@ +import * as THREE from 'three'; +import * as turf from '@turf/turf'; +import * as CONSTANTS from '../../world/worldConstants'; +import * as Types from "../../world/worldTypes"; + +function loadOnlyFloors( + floorGroup: Types.RefGroup, + linesByLayer: any, + layer: any, +): void { + + ////////// Creating polygon floor based on the onlyFloorlines.current which does not add roof to it, The lines are still stored in Lines.current as well ////////// + + let floorsInLayer = linesByLayer[layer]; + floorsInLayer = floorsInLayer.filter((line: any) => line[0][3] && line[1][3] === CONSTANTS.lineConfig.floorName); + const floorResult = floorsInLayer.map((pair: [THREE.Vector3, string, number, string][]) => + pair.map((point) => ({ + position: [point[0].x, point[0].z], + uuid: point[1] + })) + ); + const FloorLineFeatures = floorResult.map((line: any) => turf.lineString(line.map((p: any) => p.position))); + + function identifyPolygonsAndConnectedLines(FloorLineFeatures: any) { + const floorpolygons = []; + const connectedLines = []; + const unprocessedLines = [...FloorLineFeatures]; // Copy the features + + while (unprocessedLines.length > 0) { + const currentLine = unprocessedLines.pop(); + const coordinates = currentLine.geometry.coordinates; + + // Check if the line is closed (forms a polygon) + if ( + coordinates[0][0] === coordinates[coordinates.length - 1][0] && + coordinates[0][1] === coordinates[coordinates.length - 1][1] + ) { + floorpolygons.push(turf.polygon([coordinates])); // Add as a polygon + continue; + } + + // Check if the line connects to another line + let connected = false; + for (let i = unprocessedLines.length - 1; i >= 0; i--) { + const otherCoordinates = unprocessedLines[i].geometry.coordinates; + + // Check if lines share a start or end point + if ( + coordinates[0][0] === otherCoordinates[otherCoordinates.length - 1][0] && + coordinates[0][1] === otherCoordinates[otherCoordinates.length - 1][1] + ) { + // Merge lines + const mergedCoordinates = [...otherCoordinates, ...coordinates.slice(1)]; + unprocessedLines[i] = turf.lineString(mergedCoordinates); + connected = true; + break; + } else if ( + coordinates[coordinates.length - 1][0] === otherCoordinates[0][0] && + coordinates[coordinates.length - 1][1] === otherCoordinates[0][1] + ) { + // Merge lines + const mergedCoordinates = [...coordinates, ...otherCoordinates.slice(1)]; + unprocessedLines[i] = turf.lineString(mergedCoordinates); + connected = true; + break; + } + } + + if (!connected) { + connectedLines.push(currentLine); // Add unconnected line as-is + } + } + + return { floorpolygons, connectedLines }; + } + + const { floorpolygons, connectedLines } = identifyPolygonsAndConnectedLines(FloorLineFeatures); + + function convertConnectedLinesToPolygons(connectedLines: any) { + return connectedLines.map((line: any) => { + const coordinates = line.geometry.coordinates; + + // If the line has more than two points, close the polygon + if (coordinates.length > 2) { + const firstPoint = coordinates[0]; + const lastPoint = coordinates[coordinates.length - 1]; + + // Check if already closed; if not, close it + if (firstPoint[0] !== lastPoint[0] || firstPoint[1] !== lastPoint[1]) { + coordinates.push(firstPoint); + } + + // Convert the closed line into a polygon + return turf.polygon([coordinates]); + } + + // If not enough points for a polygon, return the line unchanged + return line; + }); + } + + const convertedConnectedPolygons = convertConnectedLinesToPolygons(connectedLines); + + if (convertedConnectedPolygons.length > 0) { + const validPolygons = convertedConnectedPolygons.filter( + (polygon: any) => polygon.geometry?.type === "Polygon" + ); + + if (validPolygons.length > 0) { + floorpolygons.push(...validPolygons); + } + } + + function convertPolygonsToOriginalFormat(floorpolygons: any, originalLines: [THREE.Vector3, string, number, string][][]) { + return floorpolygons.map((polygon: any) => { + const coordinates = polygon.geometry.coordinates[0]; // Extract the coordinates array (assume it's a single polygon) + + // Map each coordinate back to its original structure + const mappedPoints = coordinates.map((coord: [number, number]) => { + const [x, z] = coord; + + // Find the original point matching this coordinate + const originalPoint = originalLines.flat().find(([point]) => point.x === x && point.z === z); + + if (!originalPoint) { + throw new Error(`Original point for coordinate [${x}, ${z}] not found.`); + } + + return originalPoint; + }); + + // Create pairs of consecutive points + const pairs: typeof originalLines = []; + for (let i = 0; i < mappedPoints.length - 1; i++) { + pairs.push([mappedPoints[i], mappedPoints[i + 1]]); + } + + return pairs; + }); + } + + const convertedFloorPolygons: Types.OnlyFloorLines = convertPolygonsToOriginalFormat(floorpolygons, floorsInLayer); + + convertedFloorPolygons.forEach((floor) => { + const points: THREE.Vector3[] = []; + + floor.forEach((lineSegment) => { + const startPoint = lineSegment[0][0]; + points.push(new THREE.Vector3(startPoint.x, startPoint.y, startPoint.z)); + }); + + const lastLine = floor[floor.length - 1]; + const endPoint = lastLine[1][0]; + points.push(new THREE.Vector3(endPoint.x, endPoint.y, endPoint.z)); + + const shape = new THREE.Shape(); + shape.moveTo(points[0].x, points[0].z); + + points.forEach(point => shape.lineTo(point.x, point.z)); + shape.closePath(); + + const extrudeSettings = { + depth: CONSTANTS.floorConfig.height, + bevelEnabled: false + }; + + const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings); + const material = new THREE.MeshStandardMaterial({ color: CONSTANTS.floorConfig.defaultColor, side: THREE.DoubleSide }); + const mesh = new THREE.Mesh(geometry, material); + + mesh.castShadow = true; + mesh.receiveShadow = true; + + mesh.position.y = (floor[0][0][2] - 1) * CONSTANTS.wallConfig.height + 0.03; + mesh.rotateX(Math.PI / 2); + mesh.name = `Only_Floor_Line_${floor[0][0][2]}`; + + mesh.userData = floor; + floorGroup?.current?.add(mesh); + }); +} + +export default loadOnlyFloors; diff --git a/frontend/src/components/scene/geomentries/floors/updateFloorLines.ts b/frontend/src/components/scene/geomentries/floors/updateFloorLines.ts new file mode 100644 index 0000000..db1a990 --- /dev/null +++ b/frontend/src/components/scene/geomentries/floors/updateFloorLines.ts @@ -0,0 +1,24 @@ +import * as Types from "../../world/worldTypes"; + +function updateFloorLines( + onlyFloorlines: Types.RefOnlyFloorLines, + DragedPoint: Types.Mesh | { uuid: string, position: Types.Vector3 } +): void { + + ////////// Update onlyFloorlines.current if it contains the dragged point ////////// + + onlyFloorlines.current.forEach((floorline) => { + floorline.forEach((line) => { + line.forEach((point) => { + const [position, uuid] = point; + if (uuid === DragedPoint.uuid) { + position.x = DragedPoint.position.x; + position.y = 0.01; + position.z = DragedPoint.position.z; + } + }); + }); + }); +} + +export default updateFloorLines; diff --git a/frontend/src/components/scene/geomentries/layers/deleteLayer.ts b/frontend/src/components/scene/geomentries/layers/deleteLayer.ts new file mode 100644 index 0000000..3c6c58d --- /dev/null +++ b/frontend/src/components/scene/geomentries/layers/deleteLayer.ts @@ -0,0 +1,89 @@ +import { toast } from 'react-toastify'; +import RemoveConnectedLines from '../lines/removeConnectedLines'; + +import * as Types from '../../world/worldTypes'; +import { Socket } from 'socket.io-client'; +import { deleteLayer } from '../../../../services/factoryBuilder/lines/deleteLayerApi'; + +async function DeleteLayer( + removedLayer: Types.Number, + lines: Types.RefLines, + floorPlanGroupLine: Types.RefGroup, + floorPlanGroupPoint: Types.RefGroup, + onlyFloorlines: Types.RefOnlyFloorLines, + floorGroup: Types.RefGroup, + setDeletedLines: any, + setRemovedLayer: Types.setRemoveLayerSetState, + socket: Socket +): Promise { + + ////////// Remove the Lines from the lines.current based on the removed layer and rearrange the layer number that are higher than the removed layer ////////// + + const removedLines: Types.Lines = lines.current.filter(line => line[0][2] === removedLayer); + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // await deleteLayer(organization, removedLayer); + + //SOCKET + + const data = { + organization: organization, + layer: removedLayer, + socketId: socket.id + } + + socket.emit('v1:Line:delete:layer', data); + + ////////// Remove Points and lines from the removed layer ////////// + + removedLines.forEach((line) => { + line.forEach((removedPoint) => { + RemoveConnectedLines(removedPoint[1], floorPlanGroupLine, floorPlanGroupPoint, setDeletedLines, lines); + }); + }); + + ////////// Update the remaining lines layer values in the userData and in lines.current ////////// + + let remaining = lines.current.filter(line => line[0][2] !== removedLayer); + let updatedLines: Types.Lines = []; + remaining.forEach(line => { + let newLines: Types.Line = [...line]; + if (newLines[0][2] > removedLayer) { + newLines[0][2] -= 1; + newLines[1][2] -= 1; + } + + const matchingLine = floorPlanGroupLine.current.children.find(l => l.userData.linePoints[0][1] === line[0][1] && l.userData.linePoints[1][1] === line[1][1]); + if (matchingLine) { + const updatedUserData = matchingLine.userData; + updatedUserData.linePoints[0][2] = newLines[0][2]; + updatedUserData.linePoints[1][2] = newLines[1][2]; + } + updatedLines.push(newLines); + }); + + lines.current = updatedLines; + localStorage.setItem("Lines", JSON.stringify(lines.current)); + + ////////// Also remove OnlyFloorLines and update it in localstorage ////////// + + onlyFloorlines.current = onlyFloorlines.current.filter((floor) => { + return floor[0][0][2] !== removedLayer; + }); + const meshToRemove: any = floorGroup.current?.children.find((mesh) => + mesh.name === `Only_Floor_Line_${removedLayer}` + ); + if (meshToRemove) { + (meshToRemove.material).dispose(); + (meshToRemove.geometry).dispose(); + floorGroup.current?.remove(meshToRemove); + } + + toast.success("Layer Removed!"); + setRemovedLayer(null); +} +export default DeleteLayer; diff --git a/frontend/src/components/scene/geomentries/layers/layer2DVisibility.ts b/frontend/src/components/scene/geomentries/layers/layer2DVisibility.ts new file mode 100644 index 0000000..f0959fc --- /dev/null +++ b/frontend/src/components/scene/geomentries/layers/layer2DVisibility.ts @@ -0,0 +1,35 @@ +import * as Types from "../../world/worldTypes"; + +function Layer2DVisibility( + activeLayer: Types.Number, + floorPlanGroup: Types.RefGroup, + floorPlanGroupLine: Types.RefGroup, + floorPlanGroupPoint: Types.RefGroup, + currentLayerPoint: Types.RefMeshArray, + dragPointControls: Types.RefDragControl +): void { + + if (floorPlanGroup.current && dragPointControls.current) { + currentLayerPoint.current = []; + floorPlanGroupLine.current.children.forEach((line) => { + const linePoints = line.userData.linePoints; + + const point1 = floorPlanGroupPoint.current.getObjectByProperty('uuid', linePoints[0][1]) as Types.Mesh; + const point2 = floorPlanGroupPoint.current.getObjectByProperty('uuid', linePoints[1][1]) as Types.Mesh; + + if (linePoints[0][2] !== activeLayer && linePoints[1][2] !== activeLayer) { + point1.visible = false; + point2.visible = false; + line.visible = false; + } else { + point1.visible = true; + point2.visible = true; + line.visible = true; + currentLayerPoint.current.push(point1, point2); + } + }); + dragPointControls.current!.objects = currentLayerPoint.current; + } +} + +export default Layer2DVisibility; diff --git a/frontend/src/components/scene/geomentries/lines/addLineToScene.ts b/frontend/src/components/scene/geomentries/lines/addLineToScene.ts new file mode 100644 index 0000000..d1de51f --- /dev/null +++ b/frontend/src/components/scene/geomentries/lines/addLineToScene.ts @@ -0,0 +1,24 @@ +import * as THREE from "three"; +import * as CONSTANTS from '../../world/worldConstants'; +import * as Types from "../../world/worldTypes"; + +function addLineToScene( + start: Types.Vector3, + end: Types.Vector3, + colour: Types.Color, + userData: Types.UserData, + floorPlanGroupLine: Types.RefGroup +): void { + + ////////// A function that creates and adds lines based on the start, end, and colour from the params, Also adds the userData in the mesh userData ////////// + + const path = new THREE.CatmullRomCurve3([start, end]); + const geometry = new THREE.TubeGeometry(path, CONSTANTS.lineConfig.tubularSegments, CONSTANTS.lineConfig.radius, CONSTANTS.lineConfig.radialSegments, false); + const material = new THREE.MeshBasicMaterial({ color: colour }); + const mesh = new THREE.Mesh(geometry, material); + floorPlanGroupLine.current.add(mesh); + + mesh.userData.linePoints = userData; +} + +export default addLineToScene; diff --git a/frontend/src/components/scene/geomentries/lines/createAndMoveReferenceLine.ts b/frontend/src/components/scene/geomentries/lines/createAndMoveReferenceLine.ts new file mode 100644 index 0000000..9ec93e4 --- /dev/null +++ b/frontend/src/components/scene/geomentries/lines/createAndMoveReferenceLine.ts @@ -0,0 +1,98 @@ +import * as THREE from "three"; +import * as CONSTANTS from '../../world/worldConstants'; +import * as Types from "../../world/worldTypes"; + +function createAndMoveReferenceLine( + point: Types.Vector3, + cursorPosition: Types.Vector3, + isSnapped: Types.RefBoolean, + ispreSnapped: Types.RefBoolean, + line: Types.RefLine, + setRefTextUpdate: Types.NumberIncrementState, + floorPlanGroup: Types.RefGroup, + ReferenceLineMesh: Types.RefMesh, + LineCreated: Types.RefBoolean, + Tube: Types.RefTubeGeometry, + anglesnappedPoint: Types.RefVector3, + isAngleSnapped: Types.RefBoolean +): void { + + ////////// Creating new and maintaining the old reference line and also snap the reference line based on its angle ////////// + + const startPoint = point; + + const dx = cursorPosition.x - startPoint.x; + const dz = cursorPosition.z - startPoint.z; + let angle = Math.atan2(dz, dx); + + angle = (angle * 180) / Math.PI; + angle = (angle + 360) % 360; + + const snapAngles = [0, 90, 180, 270, 360]; + const snapThreshold = 2.5; + + const closestSnapAngle = snapAngles.reduce((prev, curr) => + Math.abs(curr - angle) < Math.abs(prev - angle) ? curr : prev + ); + + if (!isSnapped.current && !ispreSnapped.current && line.current.length > 0) { + if (Math.abs(closestSnapAngle - angle) <= snapThreshold) { + const snappedAngleRad = (closestSnapAngle * Math.PI) / 180; + const distance = Math.sqrt(dx * dx + dz * dz); + const snappedX = startPoint.x + distance * Math.cos(snappedAngleRad); + const snappedZ = startPoint.z + distance * Math.sin(snappedAngleRad); + + if ( + cursorPosition.distanceTo( + new THREE.Vector3(snappedX, 0.01, snappedZ) + ) < 2 + ) { + cursorPosition.set(snappedX, 0.01, snappedZ); + isAngleSnapped.current = true; + anglesnappedPoint.current = new THREE.Vector3( + snappedX, + 0.01, + snappedZ + ); + } else { + isAngleSnapped.current = false; + anglesnappedPoint.current = null; + } + } else { + isAngleSnapped.current = false; + anglesnappedPoint.current = null; + } + } else { + isAngleSnapped.current = false; + anglesnappedPoint.current = null; + } + + if (!LineCreated.current) { + setRefTextUpdate((prevUpdate) => prevUpdate - 1); + const path = new THREE.LineCurve3(startPoint, cursorPosition); + Tube.current = new THREE.TubeGeometry(path, CONSTANTS.lineConfig.tubularSegments, CONSTANTS.lineConfig.radius, CONSTANTS.lineConfig.radialSegments, false); + const material = new THREE.MeshBasicMaterial({ color: CONSTANTS.lineConfig.helperColor }); + ReferenceLineMesh.current = new THREE.Mesh(Tube.current, material); + ReferenceLineMesh.current.name = CONSTANTS.lineConfig.referenceName; + ReferenceLineMesh.current.userData = { + linePoints: { startPoint, cursorPosition }, + }; + floorPlanGroup.current?.add(ReferenceLineMesh.current); + LineCreated.current = true; + } else { + if (ReferenceLineMesh.current) { + const path = new THREE.LineCurve3(startPoint, new THREE.Vector3(cursorPosition.x, 0.01, cursorPosition.z)); + Tube.current = new THREE.TubeGeometry(path, CONSTANTS.lineConfig.tubularSegments, CONSTANTS.lineConfig.radius, CONSTANTS.lineConfig.radialSegments, false); + + if (ReferenceLineMesh.current) { + ReferenceLineMesh.current.userData = { + linePoints: { startPoint, cursorPosition }, + }; + ReferenceLineMesh.current.geometry.dispose(); + ReferenceLineMesh.current.geometry = Tube.current; + } + } + } +} + +export default createAndMoveReferenceLine; diff --git a/frontend/src/components/scene/geomentries/lines/deleteLine.ts b/frontend/src/components/scene/geomentries/lines/deleteLine.ts new file mode 100644 index 0000000..bf5a99d --- /dev/null +++ b/frontend/src/components/scene/geomentries/lines/deleteLine.ts @@ -0,0 +1,88 @@ +import { Socket } from "socket.io-client"; +import { deleteLineApi } from "../../../../services/factoryBuilder/lines/deleteLineApi"; +import * as Types from "../../world/worldTypes"; + +import { toast } from 'react-toastify'; + +function deleteLine( + hoveredDeletableLine: Types.RefMesh, + onlyFloorlines: Types.RefOnlyFloorLines, + lines: Types.RefLines, + floorPlanGroupLine: Types.RefGroup, + floorPlanGroupPoint: Types.RefGroup, + setDeletedLines: any, + socket: Socket +): void { + + ////////// Deleting a line and the points if they are not connected to any other line ////////// + + if (!hoveredDeletableLine.current) { + return; + } + + const linePoints = hoveredDeletableLine.current.userData.linePoints; + const connectedpoints = [linePoints[0][1], linePoints[1][1]]; + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // deleteLineApi( + // organization, + // [ + // { "uuid": linePoints[0][1] }, + // { "uuid": linePoints[1][1] } + // ] + // ) + + //SOCKET + + const data = { + organization: organization, + line: [ + { "uuid": linePoints[0][1] }, + { "uuid": linePoints[1][1] } + ], + socketId: socket.id + } + + socket.emit('v1:Line:delete', data); + + + onlyFloorlines.current = onlyFloorlines.current.map(floorline => + floorline.filter(line => line[0][1] !== connectedpoints[0] && line[1][1] !== connectedpoints[1]) + ).filter(floorline => floorline.length > 0); + + lines.current = lines.current.filter(item => item !== linePoints); + (hoveredDeletableLine.current.material).dispose(); + (hoveredDeletableLine.current.geometry).dispose(); + floorPlanGroupLine.current.remove(hoveredDeletableLine.current); + setDeletedLines([linePoints]); + + connectedpoints.forEach((pointUUID) => { + let isConnected = false; + floorPlanGroupLine.current.children.forEach((line) => { + const linePoints = line.userData.linePoints; + const uuid1 = linePoints[0][1]; + const uuid2 = linePoints[1][1]; + if (uuid1 === pointUUID || uuid2 === pointUUID) { + isConnected = true; + } + }); + + if (!isConnected) { + floorPlanGroupPoint.current.children.forEach((point: any) => { + if (point.uuid === pointUUID) { + (point.material).dispose(); + (point.geometry).dispose(); + floorPlanGroupPoint.current.remove(point); + } + }); + } + }); + + toast.success("Line Removed!"); +} + +export default deleteLine; diff --git a/frontend/src/components/scene/geomentries/lines/drawWall.ts b/frontend/src/components/scene/geomentries/lines/drawWall.ts new file mode 100644 index 0000000..2cf4d32 --- /dev/null +++ b/frontend/src/components/scene/geomentries/lines/drawWall.ts @@ -0,0 +1,167 @@ +import * as THREE from 'three'; +import * as CONSTANTS from '../../world/worldConstants'; + +import addPointToScene from '../points/addPointToScene'; +import addLineToScene from './addLineToScene'; +import splitLine from './splitLine'; +import removeReferenceLine from './removeReferenceLine'; +import getClosestIntersection from './getClosestIntersection'; + +import * as Types from "../../world/worldTypes"; +import arrayLineToObject from './lineConvertions/arrayLineToObject'; +import { setLine } from '../../../../services/factoryBuilder/lines/setLineApi'; +import { Socket } from 'socket.io-client'; + +async function drawWall( + raycaster: THREE.Raycaster, + plane: Types.RefMesh, + floorPlanGroupPoint: Types.RefGroup, + snappedPoint: Types.RefVector3, + isSnapped: Types.RefBoolean, + isSnappedUUID: Types.RefString, + line: Types.RefLine, + ispreSnapped: Types.RefBoolean, + anglesnappedPoint: Types.RefVector3, + isAngleSnapped: Types.RefBoolean, + lines: Types.RefLines, + floorPlanGroupLine: Types.RefGroup, + floorPlanGroup: Types.RefGroup, + ReferenceLineMesh: Types.RefMesh, + LineCreated: Types.RefBoolean, + currentLayerPoint: Types.RefMeshArray, + dragPointControls: Types.RefDragControl, + setNewLines: any, + setDeletedLines: any, + activeLayer: Types.Number, + socket: Socket +): Promise { + + ////////// Creating lines Based on the positions clicked ////////// + + ////////// Allows the user lines that represents walls and roof, floor if forms a polygon ////////// + + + if (!plane.current) return + let intersects = raycaster.intersectObject(plane.current, true); + + let intersectsLines = raycaster.intersectObjects(floorPlanGroupLine.current.children, true); + let intersectsPoint = raycaster.intersectObjects(floorPlanGroupPoint.current.children, true); + + const VisibleintersectsPoint = intersectsPoint.find(intersect => intersect.object.visible); + const visibleIntersect = intersectsLines.find(intersect => intersect.object.visible && intersect.object.name !== CONSTANTS.lineConfig.referenceName && intersect.object.userData.linePoints[0][3] === CONSTANTS.lineConfig.wallName); + + if ((intersectsPoint.length === 0 || VisibleintersectsPoint === undefined) && intersectsLines.length > 0 && !isSnapped.current && !ispreSnapped.current) { + + ////////// Clicked on a preexisting Line ////////// + + if (visibleIntersect && intersects) { + let IntersectsPoint = new THREE.Vector3(intersects[0].point.x, 0.01, intersects[0].point.z); + + if (isAngleSnapped.current && anglesnappedPoint.current) { + IntersectsPoint = anglesnappedPoint.current; + } + if (visibleIntersect.object instanceof THREE.Mesh) { + const ThroughPoint = (visibleIntersect.object.geometry.parameters.path).getPoints(CONSTANTS.lineConfig.lineIntersectionPoints); + let intersectionPoint = getClosestIntersection(ThroughPoint, IntersectsPoint); + + if (intersectionPoint) { + + const newLines = splitLine(visibleIntersect, intersectionPoint, currentLayerPoint, floorPlanGroupPoint, dragPointControls, isSnappedUUID, lines, setDeletedLines, floorPlanGroupLine, socket, CONSTANTS.pointConfig.wallOuterColor, CONSTANTS.lineConfig.wallColor, CONSTANTS.lineConfig.wallName); + setNewLines([newLines[0], newLines[1]]); + + (line.current as Types.Line).push([new THREE.Vector3(intersectionPoint.x, 0.01, intersectionPoint.z), isSnappedUUID.current!, activeLayer, CONSTANTS.lineConfig.wallName,]); + + if (line.current.length >= 2 && line.current[0] && line.current[1]) { + const data = arrayLineToObject(line.current as Types.Line); + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // setLine(organization, data.layer!, data.line!, data.type!); + + //SOCKET + + const input = { + organization: organization, + layer: data.layer, + line: data.line, + type: data.type, + socketId: socket.id + } + + socket.emit('v1:Line:create', input); + + setNewLines([newLines[0], newLines[1], line.current]); + lines.current.push(line.current as Types.Line); + addLineToScene(line.current[0][0], line.current[1][0], CONSTANTS.lineConfig.wallColor, line.current, floorPlanGroupLine); + let lastPoint = line.current[line.current.length - 1]; + line.current = [lastPoint]; + } + return; + } + } + } + } + + if (intersects && intersects.length > 0) { + + ////////// Clicked on a emply place or a point ////////// + + let intersectionPoint = intersects[0].point; + + if (isAngleSnapped.current && line.current.length > 0 && anglesnappedPoint.current) { + intersectionPoint = anglesnappedPoint.current; + } + if (isSnapped.current && line.current.length > 0 && snappedPoint.current) { + intersectionPoint = snappedPoint.current; + } + if (ispreSnapped.current && snappedPoint.current) { + intersectionPoint = snappedPoint.current; + } + + if (!isSnapped.current && !ispreSnapped.current) { + addPointToScene(intersectionPoint, CONSTANTS.pointConfig.wallOuterColor, currentLayerPoint, floorPlanGroupPoint, dragPointControls, isSnappedUUID, CONSTANTS.lineConfig.wallName); + } else { + ispreSnapped.current = false; + isSnapped.current = false; + } + + (line.current as Types.Line).push([new THREE.Vector3(intersectionPoint.x, 0.01, intersectionPoint.z), isSnappedUUID.current!, activeLayer, CONSTANTS.lineConfig.wallName,]); + + if (line.current.length >= 2 && line.current[0] && line.current[1]) { + const data = arrayLineToObject(line.current as Types.Line); + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // setLine(organization, data.layer!, data.line!, data.type!); + + //SOCKET + + const input = { + organization: organization, + layer: data.layer, + line: data.line, + type: data.type, + socketId: socket.id + } + + socket.emit('v1:Line:create', input); + + setNewLines([line.current]) + lines.current.push(line.current as Types.Line); + addLineToScene(line.current[0][0], line.current[1][0], CONSTANTS.lineConfig.wallColor, line.current, floorPlanGroupLine); + let lastPoint = line.current[line.current.length - 1]; + line.current = [lastPoint]; + } + if (isSnapped.current) { + removeReferenceLine(floorPlanGroup, ReferenceLineMesh, LineCreated, line); + } + } +} + +export default drawWall; diff --git a/frontend/src/components/scene/geomentries/lines/getClosestIntersection.ts b/frontend/src/components/scene/geomentries/lines/getClosestIntersection.ts new file mode 100644 index 0000000..b347f34 --- /dev/null +++ b/frontend/src/components/scene/geomentries/lines/getClosestIntersection.ts @@ -0,0 +1,26 @@ +import * as THREE from 'three'; + +import * as Types from "../../world/worldTypes"; + +function getClosestIntersection( + intersects: Types.Vector3Array, + point: Types.Vector3 +): Types.Vector3 | null { + + ////////// A function that finds which point is closest from the intersects points that is given, Used in finding which point in a line is closest when clicked on a line during drawing ////////// + + let closestNewPoint: THREE.Vector3 | null = null; + let minDistance = Infinity; + + for (const intersect of intersects) { + const distance = point.distanceTo(intersect); + if (distance < minDistance) { + minDistance = distance; + closestNewPoint = intersect; + } + } + + return closestNewPoint; +} + +export default getClosestIntersection; diff --git a/frontend/src/components/scene/geomentries/lines/getRoomsFromLines.ts b/frontend/src/components/scene/geomentries/lines/getRoomsFromLines.ts new file mode 100644 index 0000000..ad59847 --- /dev/null +++ b/frontend/src/components/scene/geomentries/lines/getRoomsFromLines.ts @@ -0,0 +1,86 @@ +import * as THREE from 'three'; +import * as turf from '@turf/turf'; +import * as CONSTANTS from '../../world/worldConstants'; +import * as Types from "../../world/worldTypes"; + +async function getRoomsFromLines(lines: Types.RefLines) { + const rooms: Types.Rooms = []; + + if (lines.current.length > 2) { + const linesByLayer = lines.current.reduce((acc: { [key: number]: any[] }, pair) => { + const layer = pair[0][2]; + if (!acc[layer]) acc[layer] = []; + acc[layer].push(pair); + return acc; + }, {}); + + ////////// Use turf.polygonize to create polygons from the line points ////////// + + for (const layer in linesByLayer) { + + let linesInLayer = linesByLayer[layer]; + linesInLayer = linesInLayer.filter(line => line[0][3] && line[1][3] === CONSTANTS.lineConfig.wallName); + const result = linesInLayer.map((pair: [THREE.Vector3, string, number, string][]) => + pair.map((point) => ({ + position: [point[0].x, point[0].z], + uuid: point[1] + })) + ); + const lineFeatures = result.map(line => turf.lineString(line.map(p => p.position))); + const polygons = turf.polygonize(turf.featureCollection(lineFeatures)); + + let union: any[] = []; + + polygons.features.forEach((feature) => { + union.push(feature); + }); + + if (union.length > 1) { + const unionResult = turf.union(turf.featureCollection(union)); + if (unionResult?.geometry.type === "MultiPolygon") { + unionResult?.geometry.coordinates.forEach((poly) => { + const Coordinates = poly[0].map(([x, z]) => { + const matchingPoint = result.flat().find(r => + r.position[0].toFixed(10) === x.toFixed(10) && + r.position[1].toFixed(10) === z.toFixed(10) + ); + return { + position: new THREE.Vector3(x, 0, z), + uuid: matchingPoint ? matchingPoint.uuid : '' + }; + }); + rooms.push({ coordinates: Coordinates.reverse(), layer: parseInt(layer) }); + }); + } else if (unionResult?.geometry.type === "Polygon") { + const Coordinates = unionResult?.geometry.coordinates[0].map(([x, z]) => { + const matchingPoint = result.flat().find(r => + r.position[0].toFixed(10) === x.toFixed(10) && + r.position[1].toFixed(10) === z.toFixed(10) + ); + return { + position: new THREE.Vector3(x, 0, z), + uuid: matchingPoint ? matchingPoint.uuid : '' + }; + }); + rooms.push({ coordinates: Coordinates.reverse(), layer: parseInt(layer) }); + } + } else if (union.length === 1) { + const Coordinates = union[0].geometry.coordinates[0].map(([x, z]: [number, number]) => { + const matchingPoint = result.flat().find(r => + r.position[0].toFixed(10) === x.toFixed(10) && + r.position[1].toFixed(10) === z.toFixed(10) + ); + return { + position: new THREE.Vector3(x, 0, z), + uuid: matchingPoint ? matchingPoint.uuid : '' + }; + }); + rooms.push({ coordinates: Coordinates, layer: parseInt(layer) }); + } + } + } + + return rooms; +} + +export default getRoomsFromLines; diff --git a/frontend/src/components/scene/geomentries/lines/lineConvertions/arrayLineToObject.ts b/frontend/src/components/scene/geomentries/lines/lineConvertions/arrayLineToObject.ts new file mode 100644 index 0000000..343c5ae --- /dev/null +++ b/frontend/src/components/scene/geomentries/lines/lineConvertions/arrayLineToObject.ts @@ -0,0 +1,24 @@ +import * as Types from "../../../world/worldTypes"; + +export default function arrayLineToObject(array: Types.Line) { + if (!Array.isArray(array)) { + return {}; + } + + // Extract common properties from the first point + const commonLayer = array[0][2]; + const commonType = array[0][3]; + + // Map points into a structured format + const line = array.map(([position, uuid]) => ({ + position, + uuid, + })); + + // Create the final structured object + return { + layer: commonLayer, + type: commonType, + line, + }; +} \ No newline at end of file diff --git a/frontend/src/components/scene/geomentries/lines/lineConvertions/arrayLinesToObject.ts b/frontend/src/components/scene/geomentries/lines/lineConvertions/arrayLinesToObject.ts new file mode 100644 index 0000000..788a6d7 --- /dev/null +++ b/frontend/src/components/scene/geomentries/lines/lineConvertions/arrayLinesToObject.ts @@ -0,0 +1,30 @@ +import * as Types from "../../../world/worldTypes"; + +export default function arrayLinesToObject(array: Array) { + if (!Array.isArray(array)) { + return []; + } + + return array.map((lineArray) => { + if (!Array.isArray(lineArray)) { + return null; + } + + // Extract common properties from the first point + const commonLayer = lineArray[0][2]; + const commonType = lineArray[0][3]; + + // Map points into a structured format + const line = lineArray.map(([position, uuid]) => ({ + position, + uuid, + })); + + // Create the final structured object + return { + layer: commonLayer, + type: commonType, + line, + }; + }).filter((item) => item !== null); // Filter out invalid entries +} diff --git a/frontend/src/components/scene/geomentries/lines/lineConvertions/objectLineToArray.ts b/frontend/src/components/scene/geomentries/lines/lineConvertions/objectLineToArray.ts new file mode 100644 index 0000000..a6ee7ea --- /dev/null +++ b/frontend/src/components/scene/geomentries/lines/lineConvertions/objectLineToArray.ts @@ -0,0 +1,13 @@ +import * as THREE from 'three'; + +export default function objectLineToArray(structuredObject: any) { + if (!structuredObject || !structuredObject.line) { + return []; + } + + // Destructure common properties + const { layer, type, line } = structuredObject; + + // Map points back to the original array format + return line.map(({ position, uuid }: any) => [new THREE.Vector3(position.x, position.y, position.z), uuid, layer, type]); +} \ No newline at end of file diff --git a/frontend/src/components/scene/geomentries/lines/lineConvertions/objectLinesToArray.ts b/frontend/src/components/scene/geomentries/lines/lineConvertions/objectLinesToArray.ts new file mode 100644 index 0000000..7f84195 --- /dev/null +++ b/frontend/src/components/scene/geomentries/lines/lineConvertions/objectLinesToArray.ts @@ -0,0 +1,20 @@ +import * as THREE from 'three'; + +export default function objectLinesToArray(structuredObjects: any): any { + if (!Array.isArray(structuredObjects)) { + return []; + } + + return structuredObjects.map((structuredObject) => { + if (!structuredObject || !structuredObject.line) { + return []; + } + + const { layer, type, line } = structuredObject; + + return line.map(({ position, uuid }: any) => { + const vector = new THREE.Vector3(position.x, position.y, position.z); + return [vector, uuid, layer, type]; + }); + }); +} diff --git a/frontend/src/components/scene/geomentries/lines/removeConnectedLines.ts b/frontend/src/components/scene/geomentries/lines/removeConnectedLines.ts new file mode 100644 index 0000000..bc85161 --- /dev/null +++ b/frontend/src/components/scene/geomentries/lines/removeConnectedLines.ts @@ -0,0 +1,66 @@ +import * as THREE from 'three'; + +import * as Types from "../../world/worldTypes"; + +function RemoveConnectedLines( + DeletedPointUUID: Types.String, + floorPlanGroupLine: Types.RefGroup, + floorPlanGroupPoint: Types.RefGroup, + setDeletedLines: any, + lines: Types.RefLines, +): void { + + ////////// Check if any and how many lines are connected to the deleted point ////////// + + const removableLines: THREE.Mesh[] = []; + const connectedpoints: string[] = []; + + const removedLinePoints: [number, string, number][][] = []; // Array to hold linePoints of removed lines + + floorPlanGroupLine.current.children.forEach((line) => { + const linePoints = line.userData.linePoints as [number, string, number][]; + const uuid1 = linePoints[0][1]; + const uuid2 = linePoints[1][1]; + + if (uuid1 === DeletedPointUUID || uuid2 === DeletedPointUUID) { + connectedpoints.push(uuid1 === DeletedPointUUID ? uuid2 : uuid1); + removableLines.push(line as THREE.Mesh); + removedLinePoints.push(linePoints); + } + }); + + if (removableLines.length > 0) { + removableLines.forEach((line) => { + lines.current = lines.current.filter(item => item !== line.userData.linePoints); + (line.material).dispose(); + (line.geometry).dispose(); + floorPlanGroupLine.current.remove(line); + }); + } + setDeletedLines(removedLinePoints) + + ////////// Check and Remove point that are no longer connected to any lines ////////// + + connectedpoints.forEach((pointUUID) => { + let isConnected = false; + floorPlanGroupLine.current.children.forEach((line) => { + const linePoints = line.userData.linePoints as [number, string, number][]; + const uuid1 = linePoints[0][1]; + const uuid2 = linePoints[1][1]; + if (uuid1 === pointUUID || uuid2 === pointUUID) { + isConnected = true; + } + }); + if (!isConnected) { + floorPlanGroupPoint.current.children.forEach((point: any) => { + if (point.uuid === pointUUID) { + (point.material).dispose(); + (point.geometry).dispose(); + floorPlanGroupPoint.current.remove(point); + } + }); + } + }); +} + +export default RemoveConnectedLines; diff --git a/frontend/src/components/scene/geomentries/lines/removeReferenceLine.ts b/frontend/src/components/scene/geomentries/lines/removeReferenceLine.ts new file mode 100644 index 0000000..1c3fc22 --- /dev/null +++ b/frontend/src/components/scene/geomentries/lines/removeReferenceLine.ts @@ -0,0 +1,22 @@ +import * as Types from "../../world/worldTypes"; + +function removeReferenceLine( + floorPlanGroup: Types.RefGroup, + ReferenceLineMesh: Types.RefMesh, + LineCreated: Types.RefBoolean, + line: Types.RefLine +): void { + + ////////// Removes Dangling reference line if the draw mode is ended or any other case ////////// + + line.current = []; + if (ReferenceLineMesh.current) { + (ReferenceLineMesh.current.material).dispose(); + (ReferenceLineMesh.current.geometry).dispose(); + floorPlanGroup.current.remove(ReferenceLineMesh.current); + LineCreated.current = false; + ReferenceLineMesh.current = undefined; + } +} + +export default removeReferenceLine; \ No newline at end of file diff --git a/frontend/src/components/scene/geomentries/lines/splitLine.ts b/frontend/src/components/scene/geomentries/lines/splitLine.ts new file mode 100644 index 0000000..77f3c97 --- /dev/null +++ b/frontend/src/components/scene/geomentries/lines/splitLine.ts @@ -0,0 +1,124 @@ +import * as THREE from 'three'; + +import addLineToScene from './addLineToScene'; +import addPointToScene from '../points/addPointToScene'; + +import * as Types from "../../world/worldTypes"; +import { deleteLineApi } from '../../../../services/factoryBuilder/lines/deleteLineApi'; +import arrayLineToObject from '../lines/lineConvertions/arrayLineToObject'; +import { setLine } from '../../../../services/factoryBuilder/lines/setLineApi'; +import { Socket } from 'socket.io-client'; + +function splitLine( + visibleIntersect: Types.IntersectionEvent, + intersectionPoint: Types.Vector3, + currentLayerPoint: Types.RefMeshArray, + floorPlanGroupPoint: Types.RefGroup, + dragPointControls: Types.RefDragControl, + isSnappedUUID: Types.RefString, + lines: Types.RefLines, + setDeletedLines: any, + floorPlanGroupLine: { current: THREE.Group }, + socket: Socket, + pointColor: Types.String, + lineColor: Types.String, + lineType: Types.String, +): [Types.Line, Types.Line] { + + ////////// Removing the clicked line and splitting it with the clicked position adding a new point and two new lines ////////// + + + ((visibleIntersect.object as any).material).dispose(); + ((visibleIntersect.object as any).geometry).dispose(); + floorPlanGroupLine.current.remove(visibleIntersect.object); + setDeletedLines([visibleIntersect.object.userData.linePoints]); + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // deleteLineApi( + // organization, + // [ + // { "uuid": visibleIntersect.object.userData.linePoints[0][1] }, + // { "uuid": visibleIntersect.object.userData.linePoints[1][1] } + // ] + // ) + + //SOCKET + + + const data = { + organization: organization, + line: [ + { "uuid": visibleIntersect.object.userData.linePoints[0][1] }, + { "uuid": visibleIntersect.object.userData.linePoints[1][1] } + ], + socketId: socket.id + } + + socket.emit('v1:Line:delete', data); + + const point = addPointToScene(intersectionPoint, pointColor, currentLayerPoint, floorPlanGroupPoint, dragPointControls, isSnappedUUID, lineType); + + const oldLinePoints = visibleIntersect.object.userData.linePoints; + lines.current = lines.current.filter(item => item !== oldLinePoints); + + const clickedPoint: Types.Point = [ + new THREE.Vector3(intersectionPoint.x, 0.01, intersectionPoint.z), + point.uuid, + oldLinePoints[0][2], + lineType + ]; + + const start = oldLinePoints[0]; + const end = oldLinePoints[1]; + + const newLine1: Types.Line = [start, clickedPoint]; + const newLine2: Types.Line = [clickedPoint, end]; + + const line1 = arrayLineToObject(newLine1); + const line2 = arrayLineToObject(newLine2); + + //REST + + // setLine(organization, line1.layer!, line1.line!, line1.type!); + + //SOCKET + + const input1 = { + organization: organization, + layer: line1.layer, + line: line1.line, + type: line1.type, + socketId: socket.id + } + + socket.emit('v1:Line:create', input1); + + //REST + + // setLine(organization, line2.layer!, line2.line!, line2.type!); + + //SOCKET + + const input2 = { + organization: organization, + layer: line2.layer, + line: line2.line, + type: line2.type, + socketId: socket.id + } + + socket.emit('v1:Line:create', input2); + + lines.current.push(newLine1, newLine2); + + addLineToScene(newLine1[0][0], newLine1[1][0], lineColor, newLine1, floorPlanGroupLine); + addLineToScene(newLine2[0][0], newLine2[1][0], lineColor, newLine2, floorPlanGroupLine); + + return [newLine1, newLine2]; +} + +export default splitLine; diff --git a/frontend/src/components/scene/geomentries/lines/updateLines.ts b/frontend/src/components/scene/geomentries/lines/updateLines.ts new file mode 100644 index 0000000..14b1762 --- /dev/null +++ b/frontend/src/components/scene/geomentries/lines/updateLines.ts @@ -0,0 +1,24 @@ +import * as THREE from 'three'; +import * as Types from "../../world/worldTypes"; +import * as CONSTANTS from '../../world/worldConstants'; + +function updateLines( + floorPlanGroupLine: Types.RefGroup, + affectedLines: Types.NumberArray +): void { + + ////////// Updating the positions for the affected lines only based on the updated positions ////////// + + affectedLines.forEach((lineIndex) => { + const mesh = floorPlanGroupLine.current.children[lineIndex] as Types.Mesh; + const linePoints = mesh.userData.linePoints as Types.Line; + if (linePoints) { + const newPositions = linePoints.map(([pos]) => pos); + const newPath = new THREE.CatmullRomCurve3(newPositions); + mesh.geometry.dispose(); + mesh.geometry = new THREE.TubeGeometry(newPath, CONSTANTS.lineConfig.tubularSegments, CONSTANTS.lineConfig.radius, CONSTANTS.lineConfig.radialSegments, false); + } + }); +} + +export default updateLines; \ No newline at end of file diff --git a/frontend/src/components/scene/geomentries/lines/updateLinesPositions.ts b/frontend/src/components/scene/geomentries/lines/updateLinesPositions.ts new file mode 100644 index 0000000..6b2fabd --- /dev/null +++ b/frontend/src/components/scene/geomentries/lines/updateLinesPositions.ts @@ -0,0 +1,32 @@ +import * as Types from "../../world/worldTypes"; + +function updateLinesPositions( + DragedPoint: Types.Mesh | { uuid: string, position: Types.Vector3 }, + lines: Types.RefLines +): Types.NumberArray { + + ////////// Updating the lines position based on the dragged point's position ////////// + + const objectUUID = DragedPoint.uuid; + const affectedLines: Types.NumberArray = []; + + lines.current.forEach((line, index) => { + let lineUpdated = false; + line.forEach((point) => { + const [position, uuid] = point; + if (uuid === objectUUID) { + position.x = DragedPoint.position.x; + position.y = 0.01; + position.z = DragedPoint.position.z; + lineUpdated = true; + } + }); + if (lineUpdated) { + affectedLines.push(index); + } + }); + + return affectedLines; +} + +export default updateLinesPositions; diff --git a/frontend/src/components/scene/geomentries/lines/vectorizeLinesCurrent.ts b/frontend/src/components/scene/geomentries/lines/vectorizeLinesCurrent.ts new file mode 100644 index 0000000..adaadd7 --- /dev/null +++ b/frontend/src/components/scene/geomentries/lines/vectorizeLinesCurrent.ts @@ -0,0 +1,18 @@ +import * as THREE from 'three'; + +import * as Types from "../../world/worldTypes"; + +function vectorizeLinesCurrent( + lines: Types.Lines +): Types.Lines { + + ////////// Storing a vector3 array in localstorage makes the prototype functions go puff. This function brings back the prototype functions by creating it again ////////// + + return lines.map((line) => { + const p1: Types.Point = [new THREE.Vector3(line[0][0].x, line[0][0].y, line[0][0].z), line[0][1], line[0][2], line[0][3],]; + const p2: Types.Point = [new THREE.Vector3(line[1][0].x, line[1][0].y, line[1][0].z), line[1][1], line[0][2], line[1][3],]; + return [p1, p2]; + }); +} + +export default vectorizeLinesCurrent; diff --git a/frontend/src/components/scene/geomentries/pillars/addAndUpdateReferencePillar.ts b/frontend/src/components/scene/geomentries/pillars/addAndUpdateReferencePillar.ts new file mode 100644 index 0000000..272c793 --- /dev/null +++ b/frontend/src/components/scene/geomentries/pillars/addAndUpdateReferencePillar.ts @@ -0,0 +1,54 @@ +import * as THREE from 'three'; +import updateReferencePolesheight from './updateReferencePolesheight'; + +import * as Types from "../../world/worldTypes"; + +function addAndUpdateReferencePillar( + raycaster: THREE.Raycaster, + floorGroup: Types.RefGroup, + referencePole: Types.RefMesh +): void { + + ////////// Find Pillars position and scale based on the pointer interaction ////////// + + let Roofs = raycaster.intersectObjects(floorGroup.current.children, true); + const intersected = Roofs.find(intersect => intersect.object.name.includes("Roof") || intersect.object.name.includes("Floor")); + + if (intersected) { + const intersectionPoint = intersected.point; + raycaster.ray.origin.copy(intersectionPoint); + raycaster.ray.direction.set(0, -1, 0); + const belowIntersections = raycaster.intersectObjects(floorGroup.current.children, true); + const validIntersections = belowIntersections.filter(intersect => intersect.object.name.includes("Floor")); + + let distance: Types.Number; + + if (validIntersections.length > 1) { + let valid = validIntersections.find(intersectedBelow => intersected.point.distanceTo(intersectedBelow.point) > 3); + if (valid) { + updateReferencePolesheight(intersectionPoint, valid.distance, referencePole, floorGroup); + } else { + const belowPoint = new THREE.Vector3(intersectionPoint.x, 0, intersectionPoint.z); + distance = intersected.point.distanceTo(belowPoint); + if (distance > 3) { + updateReferencePolesheight(intersectionPoint, distance, referencePole, floorGroup); + } + } + } else { + const belowPoint = new THREE.Vector3(intersectionPoint.x, 0, intersectionPoint.z); + distance = intersected.point.distanceTo(belowPoint); + if (distance > 3) { + updateReferencePolesheight(intersectionPoint, distance, referencePole, floorGroup); + } + } + } else { + if (referencePole.current) { + (referencePole.current.material).dispose(); + (referencePole.current.geometry).dispose(); + floorGroup.current.remove(referencePole.current); + referencePole.current = null; + } + } +} + +export default addAndUpdateReferencePillar; diff --git a/frontend/src/components/scene/geomentries/pillars/addPillar.ts b/frontend/src/components/scene/geomentries/pillars/addPillar.ts new file mode 100644 index 0000000..5b1cb9a --- /dev/null +++ b/frontend/src/components/scene/geomentries/pillars/addPillar.ts @@ -0,0 +1,24 @@ +import * as THREE from 'three'; +import * as CONSTANTS from '../../world/worldConstants'; +import * as Types from "../../world/worldTypes"; + +function addPillar( + referencePole: Types.RefMesh, + floorGroup: Types.RefGroup +): void { + + ////////// Add Pillars to the scene based on the reference. current poles position and scale ////////// + + if (referencePole.current) { + let pole: THREE.Mesh; + const geometry = referencePole.current.userData.geometry.clone(); + const material = new THREE.MeshStandardMaterial({ color: CONSTANTS.columnConfig.defaultColor }); + pole = new THREE.Mesh(geometry, material); + pole.rotateX(Math.PI / 2); + pole.name = "Pole"; + pole.position.set(referencePole.current.userData.position.x, referencePole.current.userData.position.y, referencePole.current.userData.position.z); + floorGroup.current.add(pole); + } +} + +export default addPillar; \ No newline at end of file diff --git a/frontend/src/components/scene/geomentries/pillars/deletableHoveredPillar.ts b/frontend/src/components/scene/geomentries/pillars/deletableHoveredPillar.ts new file mode 100644 index 0000000..493f36e --- /dev/null +++ b/frontend/src/components/scene/geomentries/pillars/deletableHoveredPillar.ts @@ -0,0 +1,34 @@ +import * as THREE from 'three'; + +import * as Types from "../../world/worldTypes"; + +function DeletableHoveredPillar( + state: Types.ThreeState, + floorGroup: Types.RefGroup, + hoveredDeletablePillar: Types.RefMesh +): void { + + ////////// Altering the color of the hovered Pillar during the Deletion time ////////// + + const intersects = state.raycaster.intersectObjects(floorGroup.current.children, true); + const poleIntersect = intersects.find(intersect => intersect.object.name === "Pole"); + + if (poleIntersect) { + if (poleIntersect.object.name !== "Pole") { + return; + } + if (hoveredDeletablePillar.current) { + (hoveredDeletablePillar.current.material as THREE.MeshStandardMaterial).emissive = new THREE.Color("black"); + hoveredDeletablePillar.current = undefined; + } + hoveredDeletablePillar.current = poleIntersect.object as THREE.Mesh; // Type assertion + (hoveredDeletablePillar.current.material as THREE.MeshStandardMaterial).emissive = new THREE.Color("red"); + } else { + if (hoveredDeletablePillar.current) { + (hoveredDeletablePillar.current.material as THREE.MeshStandardMaterial).emissive = new THREE.Color("black"); + hoveredDeletablePillar.current = undefined; + } + } +} + +export default DeletableHoveredPillar; \ No newline at end of file diff --git a/frontend/src/components/scene/geomentries/pillars/deletePillar.ts b/frontend/src/components/scene/geomentries/pillars/deletePillar.ts new file mode 100644 index 0000000..9d20c92 --- /dev/null +++ b/frontend/src/components/scene/geomentries/pillars/deletePillar.ts @@ -0,0 +1,21 @@ +import { toast } from 'react-toastify'; + +import * as Types from "../../world/worldTypes"; + +function DeletePillar( + hoveredDeletablePillar: Types.RefMesh, + floorGroup: Types.RefGroup +): void { + + ////////// Deleting the hovered Pillar from the itemsGroup ////////// + + if (hoveredDeletablePillar.current) { + (hoveredDeletablePillar.current.material).dispose(); + (hoveredDeletablePillar.current.geometry).dispose(); + floorGroup.current.remove(hoveredDeletablePillar.current); + toast.success("Pillar Removed!"); + hoveredDeletablePillar.current = undefined; + } +} + +export default DeletePillar; diff --git a/frontend/src/components/scene/geomentries/pillars/updateReferencePolesheight.ts b/frontend/src/components/scene/geomentries/pillars/updateReferencePolesheight.ts new file mode 100644 index 0000000..3e7d2ce --- /dev/null +++ b/frontend/src/components/scene/geomentries/pillars/updateReferencePolesheight.ts @@ -0,0 +1,40 @@ +import * as THREE from 'three'; + +import * as Types from "../../world/worldTypes"; + +function updateReferencePolesheight( + intersectionPoint: Types.Vector3, + distance: Types.Number, + referencePole: Types.RefMesh, + floorGroup: Types.RefGroup +): void { + + ////////// Add a Reference Pillar and update its position and scale based on the pointer interaction ////////// + + if (referencePole.current) { + (referencePole.current.material).dispose(); + (referencePole.current.geometry).dispose(); + floorGroup.current.remove(referencePole.current); + referencePole.current.geometry.dispose(); + } + + const shape = new THREE.Shape(); + shape.moveTo(0.5, 0); + shape.absarc(0, 0, 0.5, 0, 2 * Math.PI, false); + + const extrudeSettings = { + depth: distance, + bevelEnabled: false, + }; + + const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings); + const material = new THREE.MeshBasicMaterial({ color: "green", transparent: true, opacity: 0.5 }); + referencePole.current = new THREE.Mesh(geometry, material); + referencePole.current.rotateX(Math.PI / 2); + referencePole.current.position.set(intersectionPoint.x, intersectionPoint.y - 0.01, intersectionPoint.z); + referencePole.current.userData = { geometry: geometry, distance: distance, position: { x: intersectionPoint.x, y: intersectionPoint.y - 0.01, z: intersectionPoint.z } }; + + floorGroup.current.add(referencePole.current); +} + +export default updateReferencePolesheight; diff --git a/frontend/src/components/scene/geomentries/points/addPointToScene.ts b/frontend/src/components/scene/geomentries/points/addPointToScene.ts new file mode 100644 index 0000000..6cf88e8 --- /dev/null +++ b/frontend/src/components/scene/geomentries/points/addPointToScene.ts @@ -0,0 +1,65 @@ +import * as THREE from 'three'; +import * as CONSTANTS from '../../world/worldConstants'; +import * as Types from "../../world/worldTypes"; + +function addPointToScene( + position: Types.Vector3, + colour: Types.Color, + currentLayerPoint: Types.RefMeshArray, + floorPlanGroupPoint: Types.RefGroup, + dragPointControls: Types.RefDragControl | undefined, + uuid: Types.RefString | undefined, + Type: Types.String +): Types.Mesh { + + ////////// A function that creates and adds a cube (point) with an outline based on the position and colour given as params, It also updates the drag controls objects and sets the box uuid in uuid.current ////////// + + const geometry = new THREE.BoxGeometry(...CONSTANTS.pointConfig.boxScale); + const material = new THREE.ShaderMaterial({ + uniforms: { + uColor: { value: new THREE.Color(colour) }, // Blue color for the border + uInnerColor: { value: new THREE.Color(CONSTANTS.pointConfig.defaultInnerColor) }, // White color for the inner square + }, + vertexShader: ` + varying vec2 vUv; + + void main() { + vUv = uv; + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); + } + `, + fragmentShader: ` + varying vec2 vUv; + uniform vec3 uColor; + uniform vec3 uInnerColor; + + void main() { + // Define the size of the white square as a proportion of the face + float borderThickness = 0.2; // Adjust this value for border thickness + if (vUv.x > borderThickness && vUv.x < 1.0 - borderThickness && + vUv.y > borderThickness && vUv.y < 1.0 - borderThickness) { + gl_FragColor = vec4(uInnerColor, 1.0); // White inner square + } else { + gl_FragColor = vec4(uColor, 1.0); // Blue border + } + } + `, + }); + const point = new THREE.Mesh(geometry, material); + point.name = "point"; + point.userData = { type: Type, color: colour }; + point.position.set(position.x, 0.01, position.z); + + currentLayerPoint.current.push(point); + floorPlanGroupPoint.current.add(point); + if (uuid) { + uuid.current = point.uuid; + } + if (dragPointControls) { + dragPointControls.current!.objects = currentLayerPoint.current; + } + + return point; +} + +export default addPointToScene; diff --git a/frontend/src/components/scene/geomentries/points/deletePoint.ts b/frontend/src/components/scene/geomentries/points/deletePoint.ts new file mode 100644 index 0000000..cc93dd4 --- /dev/null +++ b/frontend/src/components/scene/geomentries/points/deletePoint.ts @@ -0,0 +1,57 @@ +import * as Types from "../../world/worldTypes"; + +import { toast } from 'react-toastify'; + +import RemoveConnectedLines from "../lines/removeConnectedLines"; +import { deletePointApi } from "../../../../services/factoryBuilder/lines/deletePointApi"; +import { Socket } from "socket.io-client"; + +function deletePoint( + hoveredDeletablePoint: Types.RefMesh, + onlyFloorlines: Types.RefOnlyFloorLines, + floorPlanGroupPoint: Types.RefGroup, + floorPlanGroupLine: Types.RefGroup, + lines: Types.RefLines, + setDeletedLines: any, + socket: Socket +): void { + ////////// Deleting a Point and the lines that are connected to it ////////// + + if (!hoveredDeletablePoint.current) { + return; + } + + (hoveredDeletablePoint.current.material).dispose(); + (hoveredDeletablePoint.current.geometry).dispose(); + floorPlanGroupPoint.current.remove(hoveredDeletablePoint.current); + const DeletedPointUUID = hoveredDeletablePoint.current.uuid; + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // deletePointApi(organization, DeletedPointUUID); + + //SOCKET + + const data = { + organization: organization, + uuid: DeletedPointUUID, + socketId: socket.id + } + + socket.emit('v1:Line:delete:point', data); + + ////////// Update onlyFloorlines.current to remove references to the deleted point ////////// + + onlyFloorlines.current = onlyFloorlines.current.map(floorline => + floorline.filter(line => line[0][1] !== DeletedPointUUID && line[1][1] !== DeletedPointUUID) + ).filter(floorline => floorline.length > 0); + + RemoveConnectedLines(DeletedPointUUID, floorPlanGroupLine, floorPlanGroupPoint, setDeletedLines, lines); + + toast.success("Point Removed!"); +} + +export default deletePoint; diff --git a/frontend/src/components/scene/geomentries/points/dragPoint.ts b/frontend/src/components/scene/geomentries/points/dragPoint.ts new file mode 100644 index 0000000..65c73a4 --- /dev/null +++ b/frontend/src/components/scene/geomentries/points/dragPoint.ts @@ -0,0 +1,45 @@ +import * as THREE from "three"; +import * as Types from "../../world/worldTypes"; +import * as CONSTANTS from '../../world/worldConstants'; + +import updateLinesPositions from "../lines/updateLinesPositions"; +import updateLines from "../lines/updateLines"; +import updateDistanceText from "../../../3d-ui/functions/updateDistanceText"; +import updateFloorLines from "../floors/updateFloorLines"; + +function DragPoint( + event: Types.IntersectionEvent, + floorPlanGroupPoint: Types.RefGroup, + floorPlanGroupLine: Types.RefGroup, + scene: THREE.Scene, + lines: Types.RefLines, + onlyFloorlines: Types.RefOnlyFloorLines +): void { + + ////////// Calling the line updation of the affected lines and Snapping of the point during the drag ////////// + + const snapThreshold = CONSTANTS.pointConfig.snappingThreshold; + const DragedPoint = event.object as Types.Mesh; + + floorPlanGroupPoint.current.children.forEach((point) => { + let canSnap = + ((DragedPoint.userData.type === CONSTANTS.lineConfig.wallName) && (point.userData.type === CONSTANTS.lineConfig.wallName || point.userData.type === CONSTANTS.lineConfig.floorName)) || + ((DragedPoint.userData.type === CONSTANTS.lineConfig.floorName) && (point.userData.type === CONSTANTS.lineConfig.wallName || point.userData.type === CONSTANTS.lineConfig.floorName)) || + ((DragedPoint.userData.type === CONSTANTS.lineConfig.zoneName) && point.userData.type === CONSTANTS.lineConfig.zoneName) || + ((DragedPoint.userData.type === CONSTANTS.lineConfig.aisleName) && point.userData.type === CONSTANTS.lineConfig.aisleName); + if (canSnap && point.uuid !== DragedPoint.uuid && point.visible) { + const distance = DragedPoint.position.distanceTo(point.position); + if (distance < snapThreshold) { + DragedPoint.position.copy(point.position); + } + } + }); + + const affectedLines = updateLinesPositions(DragedPoint, lines); + + updateLines(floorPlanGroupLine, affectedLines); + updateDistanceText(scene, floorPlanGroupLine, affectedLines); + updateFloorLines(onlyFloorlines, DragedPoint); +} + +export default DragPoint; \ No newline at end of file diff --git a/frontend/src/components/scene/geomentries/points/removeSoloPoint.ts b/frontend/src/components/scene/geomentries/points/removeSoloPoint.ts new file mode 100644 index 0000000..85353d8 --- /dev/null +++ b/frontend/src/components/scene/geomentries/points/removeSoloPoint.ts @@ -0,0 +1,37 @@ +import * as Types from "../../world/worldTypes"; + +function removeSoloPoint( + line: Types.RefLine, + floorPlanGroupLine: Types.RefGroup, + floorPlanGroupPoint: Types.RefGroup +): void { + + ////////// Remove the point if there is only one point and if it is not connected to any other line and also the reference line ////////// + + if (line.current[0]) { + const pointUUID = line.current[0][1]; + let isConnected = false; + + floorPlanGroupLine.current.children.forEach((line) => { + const linePoints = line.userData.linePoints; + const uuid1 = linePoints[0][1]; + const uuid2 = linePoints[1][1]; + if (uuid1 === pointUUID || uuid2 === pointUUID) { + isConnected = true; + } + }); + + if (!isConnected) { + floorPlanGroupPoint.current.children.forEach((point: any) => { + if (point.uuid === pointUUID) { + (point.material).dispose(); + (point.geometry).dispose(); + floorPlanGroupPoint.current.remove(point); + } + }); + } + line.current = []; + } +} + +export default removeSoloPoint; diff --git a/frontend/src/components/scene/geomentries/roofs/addRoofToScene.ts b/frontend/src/components/scene/geomentries/roofs/addRoofToScene.ts new file mode 100644 index 0000000..cb1f9bf --- /dev/null +++ b/frontend/src/components/scene/geomentries/roofs/addRoofToScene.ts @@ -0,0 +1,32 @@ +import * as THREE from 'three'; +import * as CONSTANTS from '../../world/worldConstants'; +import * as Types from "../../world/worldTypes"; + +function addRoofToScene( + shape: Types.Shape, + floor: Types.Number, + userData: Types.UserData, + floorGroup: Types.RefGroup +): void { + + ////////// Creating a Polygon roof from the shape of the Polygon floor ////////// + + const extrudeSettings: THREE.ExtrudeGeometryOptions = { + depth: CONSTANTS.roofConfig.height, + bevelEnabled: false + }; + + const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings); + const material = new THREE.MeshStandardMaterial({ color: CONSTANTS.roofConfig.defaultColor, side: THREE.DoubleSide, transparent: true, depthWrite: false }); + const mesh = new THREE.Mesh(geometry, material); + mesh.position.y = CONSTANTS.wallConfig.height + floor; + mesh.castShadow = true; + mesh.receiveShadow = true; + mesh.rotateX(Math.PI / 2); + mesh.userData.uuids = userData; + mesh.name = `Roof_Layer_${(floor / CONSTANTS.wallConfig.height) + 1}`; + + floorGroup.current.add(mesh); +} + +export default addRoofToScene; diff --git a/frontend/src/components/scene/geomentries/roofs/hideRoof.ts b/frontend/src/components/scene/geomentries/roofs/hideRoof.ts new file mode 100644 index 0000000..74387fe --- /dev/null +++ b/frontend/src/components/scene/geomentries/roofs/hideRoof.ts @@ -0,0 +1,47 @@ +import * as THREE from 'three'; + +import * as Types from "../../world/worldTypes"; + +function hideRoof( + visibility: Types.Boolean, + floorGroup: Types.RefGroup, + camera: THREE.Camera +): void { + + ////////// Toggles the visibility of the roof based on the camera position and the Roof visibility button on UI ////////// + + const v = new THREE.Vector3(); + const u = new THREE.Vector3(); + + if (visibility === true && floorGroup.current) { + for (const child of floorGroup.current.children) { + if (child.name.includes("Roof")) { + const roofChild = child as Types.Mesh; + roofChild.getWorldDirection(v); + camera?.getWorldDirection(u); + if (roofChild.material) { + const materials = Array.isArray(roofChild.material) ? roofChild.material : [roofChild.material]; + materials.forEach(material => { + material.visible = v.dot(u) < 0.25; + }); + } + } + } + } else { + if (floorGroup.current) { + for (const child of floorGroup.current.children) { + if (child.name.includes("Roof")) { + const roofChild = child as Types.Mesh; + if (roofChild.material) { + const materials = Array.isArray(roofChild.material) ? roofChild.material : [roofChild.material]; + materials.forEach(material => { + material.visible = false; + }); + } + } + } + } + } +} + +export default hideRoof; diff --git a/frontend/src/components/scene/geomentries/walls/addWallItems.ts b/frontend/src/components/scene/geomentries/walls/addWallItems.ts new file mode 100644 index 0000000..6339f62 --- /dev/null +++ b/frontend/src/components/scene/geomentries/walls/addWallItems.ts @@ -0,0 +1,108 @@ +import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; +import { toast } from 'react-toastify'; + +import * as THREE from 'three'; +import * as Types from "../../world/worldTypes"; +import * as CONSTANTS from '../../world/worldConstants'; +import { setWallItem } from '../../../../services/factoryBuilder/assest/wallAsset/setWallItemApi'; +import { Socket } from 'socket.io-client'; + +async function AddWallItems( + selected: Types.String, + raycaster: THREE.Raycaster, + CSGGroup: Types.RefMesh, + AssetConfigurations: Types.AssetConfigurations, + setWallItems: Types.setWallItemSetState, + socket: Socket +): Promise { + + ////////// Load Wall GLtf's and set the positions, rotation, type etc. in state and store in localstorage ////////// + + let intersects = raycaster?.intersectObject(CSGGroup.current!, true); + const wallRaycastIntersection = intersects?.find((child) => child.object.name.includes("WallRaycastReference")); + + if (wallRaycastIntersection) { + const intersectionPoint = wallRaycastIntersection; + const loader = new GLTFLoader(); + loader.load(AssetConfigurations[selected].modelUrl, async (gltf) => { + const model = gltf.scene; + model.userData = { wall: intersectionPoint.object.parent }; + model.children[0].children.forEach((child) => { + if (child.name !== "CSG_REF") { + child.castShadow = true; + child.receiveShadow = true; + } + }); + + const config = AssetConfigurations[selected]; + let positionY = typeof config.positionY === 'function' ? config.positionY(intersectionPoint) : config.positionY; + if (positionY === 0) { + positionY = Math.floor(intersectionPoint.point.y / CONSTANTS.wallConfig.height) * CONSTANTS.wallConfig.height; + } + + const newWallItem = { + type: config.type, + model: model, + modelname: selected, + scale: config.scale, + csgscale: config.csgscale, + csgposition: config.csgposition, + position: [intersectionPoint.point.x, positionY, intersectionPoint.point.z] as [number, number, number], + quaternion: intersectionPoint.object.quaternion.clone() as Types.QuaternionType + }; + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // await setWallItem( + // organization, + // model.uuid, + // newWallItem.modelname, + // newWallItem.type!, + // newWallItem.csgposition!, + // newWallItem.csgscale!, + // newWallItem.position, + // newWallItem.quaternion, + // newWallItem.scale!, + // ) + + //SOCKET + + const data = { + organization: organization, + modeluuid: model.uuid, + modelname: newWallItem.modelname, + type: newWallItem.type!, + csgposition: newWallItem.csgposition!, + csgscale: newWallItem.csgscale!, + position: newWallItem.position, + quaternion: newWallItem.quaternion, + scale: newWallItem.scale!, + socketId: socket.id + } + + socket.emit('v1:wallItems:set', data); + + setWallItems((prevItems) => { + const updatedItems = [...prevItems, newWallItem]; + + const WallItemsForStorage = updatedItems.map(item => { + const { model, ...rest } = item; + return { + ...rest, + modeluuid: model?.uuid, + }; + }); + + localStorage.setItem("WallItems", JSON.stringify(WallItemsForStorage)); + toast.success("Model Added!"); + + return updatedItems; + }); + }); + } +} + +export default AddWallItems; diff --git a/frontend/src/components/scene/geomentries/walls/deleteWallItems.ts b/frontend/src/components/scene/geomentries/walls/deleteWallItems.ts new file mode 100644 index 0000000..082354e --- /dev/null +++ b/frontend/src/components/scene/geomentries/walls/deleteWallItems.ts @@ -0,0 +1,59 @@ +import { toast } from 'react-toastify'; + +import * as Types from "../../world/worldTypes"; +import { deleteWallItem } from '../../../../services/factoryBuilder/assest/wallAsset/deleteWallItemApi'; +import { Socket } from 'socket.io-client'; + +function DeleteWallItems( + hoveredDeletableWallItem: Types.RefMesh, + setWallItems: Types.setWallItemSetState, + wallItems: Types.wallItems, + socket: Socket +): void { + + ////////// Deleting the hovered Wall GLTF from thewallItems and also update it in the localstorage ////////// + + if (hoveredDeletableWallItem.current && hoveredDeletableWallItem.current.parent) { + setWallItems([]); + let WallItemsRef = wallItems; + const removedItem = WallItemsRef.find((item) => item.model?.uuid === hoveredDeletableWallItem.current?.parent?.uuid); + const Items = WallItemsRef.filter((item) => item.model?.uuid !== hoveredDeletableWallItem.current?.parent?.uuid); + + setTimeout(async () => { + WallItemsRef = Items; + setWallItems(WallItemsRef); + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // await deleteWallItem(organization, removedItem?.model?.uuid!, removedItem?.modelname!) + + //SOCKET + + const data = { + organization: organization, + modeluuid: removedItem?.model?.uuid!, + modelname: removedItem?.modelname!, + socketId: socket.id + } + + socket.emit('v1:wallItems:delete', data); + + const WallItemsForStorage = WallItemsRef.map(item => { + const { model, ...rest } = item; + return { + ...rest, + modeluuid: model?.uuid, + }; + }); + + localStorage.setItem("WallItems", JSON.stringify(WallItemsForStorage)); + toast.success("Model Removed!"); + hoveredDeletableWallItem.current = null; + }, 50); + } +} + +export default DeleteWallItems; diff --git a/frontend/src/components/scene/geomentries/walls/hideWalls.ts b/frontend/src/components/scene/geomentries/walls/hideWalls.ts new file mode 100644 index 0000000..7e9cd15 --- /dev/null +++ b/frontend/src/components/scene/geomentries/walls/hideWalls.ts @@ -0,0 +1,45 @@ +import * as THREE from 'three'; + +import * as Types from "../../world/worldTypes"; + +function hideWalls( + visibility: Types.Boolean, + scene: THREE.Scene, + camera: THREE.Camera +): void { + + ////////// Altering the visibility of the Walls when the world direction of the wall is facing the camera ////////// + + const v = new THREE.Vector3(); + const u = new THREE.Vector3(); + + if (visibility === true) { + for (const children of scene.children) { + if (children.name === "Walls" && children.children[0]?.children.length > 0) { + children.children[0].children.forEach((child: any) => { + if (child.children[0]?.userData.WallType === "RoomWall") { + child.children[0].getWorldDirection(v); + camera.getWorldDirection(u); + if (child.children[0].material) { + child.children[0].material.visible = (2 * v.dot(u)) >= -0.5; + } + } + }); + } + } + } else { + for (const children of scene.children) { + if (children.name === "Walls" && children.children[0]?.children.length > 0) { + children.children[0].children.forEach((child: any) => { + if (child.children[0]?.userData.WallType === "RoomWall") { + if (child.children[0].material) { + child.children[0].material.visible = true; + } + } + }); + } + } + } +} + +export default hideWalls; diff --git a/frontend/src/components/scene/geomentries/walls/loadWalls.ts b/frontend/src/components/scene/geomentries/walls/loadWalls.ts new file mode 100644 index 0000000..a0093ba --- /dev/null +++ b/frontend/src/components/scene/geomentries/walls/loadWalls.ts @@ -0,0 +1,129 @@ +import * as THREE from 'three'; +import * as turf from '@turf/turf'; +import * as CONSTANTS from '../../world/worldConstants'; + +import * as Types from "../../world/worldTypes"; +import getRoomsFromLines from '../lines/getRoomsFromLines'; + +async function loadWalls( + lines: Types.RefLines, + setWalls: any, +): Promise { + ////////// Removes the old walls if any, Checks if there is any overlapping in lines if any updates it , starts function that creates floor and roof ////////// + + const Walls: Types.Walls = []; + const Rooms: Types.Rooms = []; + + localStorage.setItem("Lines", JSON.stringify(lines.current)); + + if (lines.current.length > 1) { + + ////////// Add Walls that are forming a room ////////// + + const wallSet = new Set(); + + const rooms: Types.Rooms = await getRoomsFromLines(lines); + Rooms.push(...rooms); + + Rooms.forEach(({ coordinates: room, layer }) => { + for (let i = 0; i < room.length - 1; i++) { + const uuid1 = room[i].uuid; + const uuid2 = room[(i + 1) % room.length].uuid; + const wallId = `${uuid1}_${uuid2}`; + + if (!wallSet.has(wallId)) { + const p1 = room[i].position; + const p2 = room[(i + 1) % room.length].position; + + const shape = new THREE.Shape(); + shape.moveTo(0, 0); + shape.lineTo(0, CONSTANTS.wallConfig.height); + shape.lineTo(p2.distanceTo(p1), CONSTANTS.wallConfig.height); + shape.lineTo(p2.distanceTo(p1), 0); + shape.lineTo(0, 0); + + const extrudeSettings = { + depth: CONSTANTS.wallConfig.width, + bevelEnabled: false + }; + const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings); + const angle = Math.atan2(p2.z - p1.z, p2.x - p1.x); + Walls.push([geometry, [0, -angle, 0], [p1.x, (layer - 1) * CONSTANTS.wallConfig.height, p1.z], "RoomWall", layer]); + + wallSet.add(wallId); + } + } + }); + + ////////// Add Walls that are not forming any room ////////// + + lines.current.forEach(line => { + if (line[0][3] && line[1][3] !== CONSTANTS.lineConfig.wallName) { + return; + } + const [uuid1, uuid2] = line.map(point => point[1]); + let isInRoom = false; + const lineLayer = line[0][2]; + + for (let room of Rooms) { + const roomLayer = room.layer; + if (roomLayer !== lineLayer) continue; + for (let i = 0; i < room.coordinates.length - 1; i++) { + const roomUuid1 = room.coordinates[i].uuid; + const roomUuid2 = room.coordinates[(i + 1) % room.coordinates.length].uuid; + if ( + (uuid1 === roomUuid1 && uuid2 === roomUuid2) || + (uuid1 === roomUuid2 && uuid2 === roomUuid1) + ) { + isInRoom = true; + break; + } + } + if (isInRoom) break; + } + + if (!isInRoom) { + const p1 = new THREE.Vector3(line[0][0].x, 0, line[0][0].z); + const p2 = new THREE.Vector3(line[1][0].x, 0, line[1][0].z); + + let isCollinear = false; + for (let room of Rooms) { + if (room.layer !== lineLayer) continue; + for (let i = 0; i < room.coordinates.length - 1; i++) { + const roomP1 = room.coordinates[i].position; + const roomP2 = room.coordinates[(i + 1) % room.coordinates.length].position; + const lineFeature = turf.lineString([[p1.x, p1.z], [p2.x, p2.z]]); + const roomFeature = turf.lineString([[roomP1.x, roomP1.z], [roomP2.x, roomP2.z]]); + if (turf.booleanOverlap(lineFeature, roomFeature)) { + isCollinear = true; + break; + } + } + if (isCollinear) break; + } + + if (!isCollinear) { + const shape = new THREE.Shape(); + shape.moveTo(0, 0); + shape.lineTo(0, CONSTANTS.wallConfig.height); + shape.lineTo(p2.distanceTo(p1), CONSTANTS.wallConfig.height); + shape.lineTo(p2.distanceTo(p1), 0); + shape.lineTo(0, 0); + + const extrudeSettings = { + depth: CONSTANTS.wallConfig.width, + bevelEnabled: false + }; + const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings); + const angle = Math.atan2(p2.z - p1.z, p2.x - p1.x); + Walls.push([geometry, [0, -angle, 0], [p1.x, (lineLayer - 1) * CONSTANTS.wallConfig.height, p1.z], "SegmentWall", lineLayer]); + } + } + }); + setWalls(Walls); + }else{ + setWalls([]); + } +} + +export default loadWalls; diff --git a/frontend/src/components/scene/geomentries/zones/addZonesToScene.ts b/frontend/src/components/scene/geomentries/zones/addZonesToScene.ts new file mode 100644 index 0000000..87258ec --- /dev/null +++ b/frontend/src/components/scene/geomentries/zones/addZonesToScene.ts @@ -0,0 +1,50 @@ +import * as THREE from 'three'; +import * as Types from '../../world/worldTypes'; +import * as CONSTANTS from '../../world/worldConstants'; + +const baseMaterial = new THREE.ShaderMaterial({ + side: THREE.DoubleSide, + vertexShader: ` + varying vec2 vUv; + void main(){ + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); + vUv = uv; + } + `, + fragmentShader: ` + varying vec2 vUv; + uniform vec3 uColor; + void main(){ + float alpha = 1.0 - vUv.y; + gl_FragColor = vec4(uColor, alpha); + } + `, + uniforms: { + uColor: { value: new THREE.Color(CONSTANTS.zoneConfig.defaultColor) }, + }, + transparent: true, +}); + +export default function addZonesToScene( + line: Types.Line, + floorGroupZone: Types.RefGroup, + color: THREE.Color +) { + const point1 = line[0][0]; + const point2 = line[1][0]; + + const length = (new THREE.Vector3(point2.x, point2.y, point2.z)).distanceTo(new THREE.Vector3(point1.x, point1.y, point1.z)); + const angle = Math.atan2(point2.z - point1.z, point2.x - point1.x); + + const geometry = new THREE.PlaneGeometry(length, 10); + + const material = baseMaterial.clone(); + material.uniforms.uColor.value.set(color.r, color.g, color.b); + + const mesh = new THREE.Mesh(geometry, material); + + mesh.position.set((point1.x + point2.x) / 2, ((line[0][2] - 1) * CONSTANTS.wallConfig.height) + 5, (point1.z + point2.z) / 2); + mesh.rotation.y = -angle; + + floorGroupZone.current.add(mesh); +} diff --git a/frontend/src/components/scene/geomentries/zones/loadZones.ts b/frontend/src/components/scene/geomentries/zones/loadZones.ts new file mode 100644 index 0000000..fa3b52b --- /dev/null +++ b/frontend/src/components/scene/geomentries/zones/loadZones.ts @@ -0,0 +1,19 @@ +import * as Types from '../../world/worldTypes'; +import * as THREE from 'three'; +import * as CONSTANTS from '../../world/worldConstants'; +import addZonesToScene from './addZonesToScene'; + +export default function loadZones( + lines: Types.RefLines, + floorGroupZone: Types.RefGroup +) { + if (!floorGroupZone.current) return + floorGroupZone.current.children = []; + const zones = lines.current.filter((line) => line[0][3] && line[1][3] === CONSTANTS.lineConfig.zoneName); + + if (zones.length > 0) { + zones.forEach((zone: Types.Line) => { + addZonesToScene(zone, floorGroupZone, new THREE.Color(CONSTANTS.zoneConfig.color)) + }) + } +} \ No newline at end of file diff --git a/frontend/src/components/scene/groups/floorGroup.tsx b/frontend/src/components/scene/groups/floorGroup.tsx new file mode 100644 index 0000000..a9daa2d --- /dev/null +++ b/frontend/src/components/scene/groups/floorGroup.tsx @@ -0,0 +1,101 @@ +import { useFrame, useThree } from "@react-three/fiber"; +import { useAddAction, useDeleteModels, useRoofVisibility, useToggleView, useWallVisibility, useUpdateScene } from "../../../store/store"; +import hideRoof from "../geomentries/roofs/hideRoof"; +import hideWalls from "../geomentries/walls/hideWalls"; +import addAndUpdateReferencePillar from "../geomentries/pillars/addAndUpdateReferencePillar"; +import { useEffect } from "react"; +import addPillar from "../geomentries/pillars/addPillar"; +import DeletePillar from "../geomentries/pillars/deletePillar"; +import DeletableHoveredPillar from "../geomentries/pillars/deletableHoveredPillar"; +import loadFloor from "../geomentries/floors/loadFloor"; + +const FloorGroup = ({ floorGroup, lines, referencePole, hoveredDeletablePillar }: any) => { + const state = useThree(); + const { roofVisibility, setRoofVisibility } = useRoofVisibility(); + const { wallVisibility, setWallVisibility } = useWallVisibility(); + const { toggleView, setToggleView } = useToggleView(); + const { scene, camera, pointer, raycaster, gl } = useThree(); + const { addAction, setAddAction } = useAddAction(); + const { deleteModels, setDeleteModels } = useDeleteModels(); + const { updateScene, setUpdateScene } = useUpdateScene(); + + useEffect(() => { + if (updateScene) { + loadFloor(lines, floorGroup); + setUpdateScene(false); + } + }, [updateScene]) + + useEffect(() => { + if (!addAction) { + if (referencePole.current) { + (referencePole.current as any).material.dispose(); + (referencePole.current.geometry as any).dispose(); + floorGroup.current.remove(referencePole.current); + referencePole.current = undefined; + } + } + }, [addAction]); + + useEffect(() => { + const canvasElement = gl.domElement; + let drag = false; + let isLeftMouseDown = false; + + const onMouseDown = (evt: any) => { + if (evt.button === 0) { + isLeftMouseDown = true; + drag = false; + } + }; + + const onMouseUp = (evt: any) => { + if (evt.button === 0) { + isLeftMouseDown = false; + if (!drag) { + if (addAction === "pillar") { + addPillar(referencePole, floorGroup); + } + if (deleteModels) { + DeletePillar(hoveredDeletablePillar, floorGroup); + } + } + } + }; + + const onMouseMove = () => { + if (isLeftMouseDown) { + drag = true; + } + }; + + canvasElement.addEventListener("mousedown", onMouseDown); + canvasElement.addEventListener("mouseup", onMouseUp); + canvasElement.addEventListener("mousemove", onMouseMove); + + return () => { + canvasElement.removeEventListener("mousedown", onMouseDown); + canvasElement.removeEventListener("mouseup", onMouseUp); + canvasElement.removeEventListener("mousemove", onMouseMove); + }; + }, [deleteModels, addAction]) + + useFrame(() => { + hideRoof(roofVisibility, floorGroup, camera); + hideWalls(wallVisibility, scene, camera); + + if (addAction === "pillar") { + addAndUpdateReferencePillar(raycaster, floorGroup, referencePole); + } + if (deleteModels) { + DeletableHoveredPillar(state, floorGroup, hoveredDeletablePillar); + } + }) + + return ( + + + ) +} + +export default FloorGroup; \ No newline at end of file diff --git a/frontend/src/components/scene/groups/floorGroupAisle.tsx b/frontend/src/components/scene/groups/floorGroupAisle.tsx new file mode 100644 index 0000000..bd1ff0f --- /dev/null +++ b/frontend/src/components/scene/groups/floorGroupAisle.tsx @@ -0,0 +1,245 @@ +import * as THREE from 'three'; +import * as Types from '../world/worldTypes'; +import * as CONSTANTS from '../world/worldConstants'; +import { useThree } from "@react-three/fiber"; +import { useToggleView, useActiveLayer, useSocketStore, useDeletePointOrLine, useMovePoint, useUpdateScene, useNewLines, useToolMode } from "../../../store/store"; +import { useEffect } from "react"; +import removeSoloPoint from "../geomentries/points/removeSoloPoint"; +import removeReferenceLine from "../geomentries/lines/removeReferenceLine"; +import getClosestIntersection from "../geomentries/lines/getClosestIntersection"; +import addPointToScene from "../geomentries/points/addPointToScene"; +import arrayLineToObject from '../geomentries/lines/lineConvertions/arrayLineToObject'; +import addLineToScene from "../geomentries/lines/addLineToScene"; +import loadAisles from '../geomentries/aisles/loadAisles'; + + +const FloorGroupAilse = ({ floorGroupAisle, plane, floorPlanGroupLine, floorPlanGroupPoint, line, lines, currentLayerPoint, dragPointControls, floorPlanGroup, ReferenceLineMesh, LineCreated, isSnapped, ispreSnapped, snappedPoint, isSnappedUUID, isAngleSnapped, anglesnappedPoint }: any) => { + const { toggleView, setToggleView } = useToggleView(); + const { deletePointOrLine, setDeletePointOrLine } = useDeletePointOrLine(); + const { toolMode, setToolMode } = useToolMode(); + const { movePoint, setMovePoint } = useMovePoint(); + const { socket } = useSocketStore(); + const { activeLayer } = useActiveLayer(); + const { gl, raycaster, camera, pointer } = useThree(); + const { updateScene, setUpdateScene } = useUpdateScene(); + const { newLines, setNewLines } = useNewLines(); + + useEffect(() => { + if (updateScene) { + loadAisles(lines, floorGroupAisle); + setUpdateScene(false); + } + }, [updateScene]) + + useEffect(() => { + if (toolMode === "Aisle") { + setDeletePointOrLine(false); + setMovePoint(false); + } else { + removeSoloPoint(line, floorPlanGroupLine, floorPlanGroupPoint); + removeReferenceLine(floorPlanGroup, ReferenceLineMesh, LineCreated, line); + } + }, [toolMode]); + + useEffect(() => { + + const canvasElement = gl.domElement; + + let drag = false; + let isLeftMouseDown = false; + + const onMouseDown = (evt: any) => { + if (evt.button === 0) { + isLeftMouseDown = true; + drag = false; + } + }; + + const onMouseUp = (evt: any) => { + if (evt.button === 0) { + isLeftMouseDown = false; + } + } + + const onMouseMove = () => { + if (isLeftMouseDown) { + drag = true; + } + }; + + const onContextMenu = (e: any) => { + e.preventDefault(); + if (toolMode === "Aisle") { + removeSoloPoint(line, floorPlanGroupLine, floorPlanGroupPoint); + removeReferenceLine(floorPlanGroup, ReferenceLineMesh, LineCreated, line); + } + }; + + const onMouseClick = (evt: any) => { + if (!plane.current || drag) return; + + const intersects = raycaster.intersectObject(plane.current, true); + let intersectionPoint = intersects[0].point; + const points = floorPlanGroupPoint.current?.children ?? []; + const intersectsPoint = raycaster.intersectObjects(points, true).find(intersect => intersect.object.visible); + let intersectsLines: any = raycaster.intersectObjects(floorPlanGroupLine.current.children, true); + + + if (intersectsLines.length > 0 && intersects && intersects.length > 0 && !intersectsPoint) { + const lineType = intersectsLines[0].object.userData.linePoints[0][3]; + if (lineType === CONSTANTS.lineConfig.aisleName) { + // console.log("intersected a aisle line"); + const ThroughPoint = (intersectsLines[0].object.geometry.parameters.path).getPoints(CONSTANTS.lineConfig.lineIntersectionPoints); + let intersection = getClosestIntersection(ThroughPoint, intersectionPoint); + if (!intersection) return; + const point = addPointToScene(intersection, CONSTANTS.pointConfig.aisleOuterColor, currentLayerPoint, floorPlanGroupPoint, dragPointControls, undefined, CONSTANTS.lineConfig.aisleName); + (line.current as Types.Line).push([new THREE.Vector3(intersection.x, 0.01, intersection.z), point.uuid, activeLayer, CONSTANTS.lineConfig.aisleName,]); + if (line.current.length >= 2 && line.current[0] && line.current[1]) { + lines.current.push(line.current as Types.Line); + + const data = arrayLineToObject(line.current as Types.Line); + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // setLine(organization, data.layer!, data.line!, data.type!); + + //SOCKET + + const input = { + organization: organization, + layer: data.layer, + line: data.line, + type: data.type, + socketId: socket.id + } + + socket.emit('v1:Line:create', input); + + setNewLines([line.current]); + + addLineToScene(line.current[0][0], line.current[1][0], CONSTANTS.pointConfig.aisleOuterColor, line.current, floorPlanGroupLine); + let lastPoint = line.current[line.current.length - 1]; + line.current = [lastPoint]; + } + } + } else if (intersectsPoint && intersects && intersects.length > 0) { + if (intersectsPoint.object.userData.type === CONSTANTS.lineConfig.aisleName) { + // console.log("intersected a aisle point"); + intersectionPoint = intersectsPoint.object.position; + (line.current as Types.Line).push([new THREE.Vector3(intersectionPoint.x, 0.01, intersectionPoint.z), intersectsPoint.object.uuid, activeLayer, CONSTANTS.lineConfig.aisleName,]); + if (line.current.length >= 2 && line.current[0] && line.current[1]) { + lines.current.push(line.current as Types.Line); + + const data = arrayLineToObject(line.current as Types.Line); + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // setLine(organization, data.layer!, data.line!, data.type!); + + //SOCKET + + const input = { + organization: organization, + layer: data.layer, + line: data.line, + type: data.type, + socketId: socket.id + } + + socket.emit('v1:Line:create', input); + + setNewLines([line.current]); + + addLineToScene(line.current[0][0], line.current[1][0], CONSTANTS.pointConfig.aisleOuterColor, line.current, floorPlanGroupLine); + let lastPoint = line.current[line.current.length - 1]; + line.current = [lastPoint]; + ispreSnapped.current = false; + isSnapped.current = false; + } + } + } else if (intersects && intersects.length > 0) { + // console.log("intersected a empty area"); + let uuid: string = ""; + if (isAngleSnapped.current && anglesnappedPoint.current && line.current.length > 0) { + intersectionPoint = anglesnappedPoint.current; + const point = addPointToScene(intersectionPoint, CONSTANTS.pointConfig.aisleOuterColor, currentLayerPoint, floorPlanGroupPoint, dragPointControls, undefined, CONSTANTS.lineConfig.aisleName); + uuid = point.uuid; + } else if (isSnapped.current && snappedPoint.current && line.current.length > 0) { + intersectionPoint = snappedPoint.current; + uuid = isSnappedUUID.current!; + } else if (ispreSnapped.current && snappedPoint.current) { + intersectionPoint = snappedPoint.current; + uuid = isSnappedUUID.current!; + } else { + const point = addPointToScene(intersectionPoint, CONSTANTS.pointConfig.aisleOuterColor, currentLayerPoint, floorPlanGroupPoint, dragPointControls, undefined, CONSTANTS.lineConfig.aisleName); + uuid = point.uuid; + } + (line.current as Types.Line).push([new THREE.Vector3(intersectionPoint.x, 0.01, intersectionPoint.z), uuid, activeLayer, CONSTANTS.lineConfig.aisleName,]); + + if (line.current.length >= 2 && line.current[0] && line.current[1]) { + lines.current.push(line.current as Types.Line); + + const data = arrayLineToObject(line.current as Types.Line); + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // setLine(organization, data.layer!, data.line!, data.type!); + + //SOCKET + + const input = { + organization: organization, + layer: data.layer, + line: data.line, + type: data.type, + socketId: socket.id + } + + socket.emit('v1:Line:create', input); + + setNewLines([line.current]); + + addLineToScene(line.current[0][0], line.current[1][0], CONSTANTS.pointConfig.aisleOuterColor, line.current, floorPlanGroupLine); + let lastPoint = line.current[line.current.length - 1]; + line.current = [lastPoint]; + ispreSnapped.current = false; + isSnapped.current = false; + } + } + } + + + if (toolMode === 'Aisle') { + canvasElement.addEventListener("mousedown", onMouseDown); + canvasElement.addEventListener("mouseup", onMouseUp); + canvasElement.addEventListener("mousemove", onMouseMove); + canvasElement.addEventListener("click", onMouseClick); + canvasElement.addEventListener("contextmenu", onContextMenu); + } + + return () => { + canvasElement.removeEventListener("mousedown", onMouseDown); + canvasElement.removeEventListener("mouseup", onMouseUp); + canvasElement.removeEventListener("mousemove", onMouseMove); + canvasElement.removeEventListener("click", onMouseClick); + canvasElement.removeEventListener("contextmenu", onContextMenu); + }; + }, [toolMode]) + + + return ( + + + ) +} + +export default FloorGroupAilse; \ No newline at end of file diff --git a/frontend/src/components/scene/groups/floorItemsGroup.tsx b/frontend/src/components/scene/groups/floorItemsGroup.tsx new file mode 100644 index 0000000..471f33b --- /dev/null +++ b/frontend/src/components/scene/groups/floorItemsGroup.tsx @@ -0,0 +1,279 @@ +import { useFrame, useThree } from "@react-three/fiber"; +import { useActiveTool, useCamMode, useDeletableFloorItem, useDeleteModels, useFloorItems, useRenderDistance, useselectedFloorItem, useSelectedItem, useSocketStore, useToggleView, useTransformMode } from "../../../store/store"; +import assetVisibility from "../geomentries/assets/assetVisibility"; +import { useEffect } from "react"; +import * as THREE from "three"; +import * as Types from "../world/worldTypes"; +import assetManager, { cancelOngoingTasks } from "../geomentries/assets/assetManager"; +import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; +import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader"; +import DeletableHoveredFloorItems from "../geomentries/assets/deletableHoveredFloorItems"; +import DeleteFloorItems from "../geomentries/assets/deleteFloorItems"; +import loadInitialFloorItems from "../IntialLoad/loadInitialFloorItems"; +import addAssetModel from "../geomentries/assets/addAssetModel"; +import { getFloorItems } from "../../../services/factoryBuilder/assest/floorAsset/getFloorItemsApi"; +import { retrieveGLTF } from "../indexDB/idbUtils"; +const assetManagerWorker = new Worker(new URL('../../../services/factoryBuilder/webWorkers/assetManagerWorker.js', import.meta.url)); +const gltfLoaderWorker = new Worker(new URL('../../../services/factoryBuilder/webWorkers/gltfLoaderWorker.js', import.meta.url)); + +const FloorItemsGroup = ({ itemsGroup, hoveredDeletableFloorItem, AttachedObject, floorGroup, tempLoader, isTempLoader, plane }: any) => { + const state: Types.ThreeState = useThree(); + const { raycaster, camera, controls, pointer }: any = state; + const { renderDistance, setRenderDistance } = useRenderDistance(); + const { toggleView, setToggleView } = useToggleView(); + const { floorItems, setFloorItems } = useFloorItems(); + const { camMode, setCamMode } = useCamMode(); + const { deleteModels, setDeleteModels } = useDeleteModels(); + const { deletableFloorItem, setDeletableFloorItem } = useDeletableFloorItem(); + const { transformMode, setTransformMode } = useTransformMode(); + const { selectedFloorItem, setselectedFloorItem } = useselectedFloorItem(); + const { activeTool, setActiveTool } = useActiveTool(); + const { selectedItem, setSelectedItem } = useSelectedItem(); + const { socket } = useSocketStore(); + + const loader = new GLTFLoader(); + const dracoLoader = new DRACOLoader(); + + dracoLoader.setDecoderPath('https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/'); + loader.setDRACOLoader(dracoLoader); + + useEffect(() => { + // Load initial floor items + + // const email = localStorage.getItem('email'); + // const organization = (email!.split("@")[1]).split(".")[0]; + + // getFloorItems(organization).then((data) => { + // gltfLoaderWorker.postMessage({ FloorItems: data }) + // }) + + // gltfLoaderWorker.onmessage = async (event) => { + // if (event.data.message === "gltfLoaded" && event.data.modelBlob) { + // const blobUrl = URL.createObjectURL(event.data.modelBlob); + + // loader.load(blobUrl, (gltf) => { + // URL.revokeObjectURL(blobUrl); + // THREE.Cache.remove(blobUrl); + // THREE.Cache.add(event.data.modelID, gltf); + // }); + + // } else if (event.data.message === "done") { + // loadInitialFloorItems(itemsGroup, setFloorItems); + // } + // } + + + loadInitialFloorItems(itemsGroup, setFloorItems); + }, []); + + useEffect(() => { + assetManagerWorker.onmessage = async (event) => { + cancelOngoingTasks(); // Cancel the ongoing process + await assetManager(event.data, itemsGroup, loader); + }; + }, [assetManagerWorker]); + + useEffect(() => { + if (toggleView) return + + const uuids: string[] = []; + itemsGroup.current?.children.forEach((child: any) => { + uuids.push(child.uuid); + }); + const cameraPosition = state.camera.position; + + assetManagerWorker.postMessage({ floorItems, cameraPosition, uuids, renderDistance }); + }, [camMode, renderDistance]); + + useEffect(() => { + const controls: any = state.controls; + const camera: any = state.camera; + + if (controls) { + let intervalId: NodeJS.Timeout | null = null; + + const handleChange = () => { + if (toggleView) return + + const uuids: string[] = []; + itemsGroup.current?.children.forEach((child: any) => { + uuids.push(child.uuid); + }); + const cameraPosition = camera.position; + + assetManagerWorker.postMessage({ floorItems, cameraPosition, uuids, renderDistance }); + }; + + const startInterval = () => { + if (!intervalId) { + intervalId = setInterval(handleChange, 50); + } + }; + + const stopInterval = () => { + handleChange(); + if (intervalId) { + clearInterval(intervalId); + intervalId = null; + } + }; + + controls.addEventListener('rest', handleChange); + controls.addEventListener('rest', stopInterval); + controls.addEventListener('control', startInterval); + controls.addEventListener('controlend', stopInterval); + + return () => { + controls.removeEventListener('rest', handleChange); + controls.removeEventListener('rest', stopInterval); + controls.removeEventListener('control', startInterval); + controls.removeEventListener('controlend', stopInterval); + if (intervalId) { + clearInterval(intervalId); + } + }; + } + }, [state.controls, floorItems, toggleView, renderDistance]); + + useEffect(() => { + const canvasElement = state.gl.domElement; + let drag = false; + let isLeftMouseDown = false; + + const onMouseDown = (evt: any) => { + if (evt.button === 0) { + isLeftMouseDown = true; + drag = false; + } + }; + + const onMouseMove = () => { + if (isLeftMouseDown) { + drag = true; + } + }; + + const onMouseUp = async (evt: any) => { + if (controls) { + (controls as any).enabled = true; + } + if (evt.button === 0) { + isLeftMouseDown = false; + if (drag) return; + + if (deleteModels) { + DeleteFloorItems(itemsGroup, hoveredDeletableFloorItem, setFloorItems, socket); + } + const Mode = transformMode; + + if (Mode !== null || activeTool === "Cursor") { + if (!itemsGroup.current) return; + let intersects = raycaster.intersectObjects(itemsGroup.current.children, true); + if (intersects.length === 0) { + const target = controls.getTarget(new THREE.Vector3()); + await controls.setTarget(target.x, 0, target.z, true); + setselectedFloorItem(null); + } + } + } + }; + + const onDblClick = async (evt: any) => { + if (evt.button === 0) { + isLeftMouseDown = false; + if (drag) return; + + const Mode = transformMode; + + if (Mode !== null || activeTool === "Cursor") { + if (!itemsGroup.current) return; + let intersects = raycaster.intersectObjects(itemsGroup.current.children, true); + if (intersects.length > 0 && intersects[0]?.object?.parent?.parent?.position && intersects[0]?.object?.parent?.parent?.scale && intersects[0]?.object?.parent?.parent?.rotation) { + let currentObject = intersects[0].object; + + while (currentObject) { + if (currentObject.name === "Scene") { + break; + } + currentObject = currentObject.parent as THREE.Object3D; + } + if (currentObject) { + AttachedObject.current = currentObject as any; + // controls.fitToSphere(AttachedObject.current!, true); + + const bbox = new THREE.Box3().setFromObject(AttachedObject.current); + const size = bbox.getSize(new THREE.Vector3()); + const center = bbox.getCenter(new THREE.Vector3()); + + const front = new THREE.Vector3(0, 0, 1); + AttachedObject.current.localToWorld(front); + front.sub(AttachedObject.current.position).normalize(); + + const distance = Math.max(size.x, size.y, size.z) * 2; + const newPosition = center.clone().addScaledVector(front, distance); + + controls.setPosition(newPosition.x, newPosition.y, newPosition.z, true); + controls.setTarget(center.x, center.y, center.z, true); + controls.fitToBox(AttachedObject.current!, true, { cover: true, paddingTop: 5, paddingLeft: 5, paddingBottom: 5, paddingRight: 5 }); + + setselectedFloorItem(AttachedObject.current!); + } + } else { + const target = controls.getTarget(new THREE.Vector3()); + await controls.setTarget(target.x, 0, target.z, true); + setselectedFloorItem(null); + } + } + } + } + + const onDrop = (event: any) => { + + if (!event.dataTransfer?.files[0]) return; + + if (selectedItem.id !== "" && event.dataTransfer?.files[0]) { + addAssetModel(raycaster, state.camera, state.pointer, floorGroup, setFloorItems, itemsGroup, isTempLoader, tempLoader, socket, selectedItem, setSelectedItem, plane); + } + } + + const onDragOver = (event: any) => { + event.preventDefault(); + }; + + canvasElement.addEventListener("mousedown", onMouseDown); + canvasElement.addEventListener("mouseup", onMouseUp); + canvasElement.addEventListener("mousemove", onMouseMove); + canvasElement.addEventListener("dblclick", onDblClick); + canvasElement.addEventListener("drop", onDrop); + canvasElement.addEventListener("dragover", onDragOver); + + return () => { + canvasElement.removeEventListener("mousedown", onMouseDown); + canvasElement.removeEventListener("mouseup", onMouseUp); + canvasElement.removeEventListener("mousemove", onMouseMove); + canvasElement.removeEventListener("dblclick", onDblClick); + canvasElement.removeEventListener("drop", onDrop); + canvasElement.removeEventListener("dragover", onDragOver); + }; + }, [deleteModels, transformMode, controls, selectedItem, state.camera, state.pointer, activeTool]); + + useFrame(() => { + if (controls) + assetVisibility(itemsGroup, state.camera.position, renderDistance); + if (deleteModels) { + DeletableHoveredFloorItems(state, itemsGroup, hoveredDeletableFloorItem, setDeletableFloorItem); + } else if (!deleteModels) { + if (hoveredDeletableFloorItem.current) { + hoveredDeletableFloorItem.current = undefined; + setDeletableFloorItem(null); + } + } + }) + + return ( + + + ) +} + +export default FloorItemsGroup; \ No newline at end of file diff --git a/frontend/src/components/scene/groups/floorPlanGroup.tsx b/frontend/src/components/scene/groups/floorPlanGroup.tsx new file mode 100644 index 0000000..7b4d669 --- /dev/null +++ b/frontend/src/components/scene/groups/floorPlanGroup.tsx @@ -0,0 +1,197 @@ +import { useEffect } from "react"; +import * as Types from '../world/worldTypes'; +import { useActiveLayer, useDeletedLines, useDeletePointOrLine, useToolMode, useMovePoint, useNewLines, useRemovedLayer, useSocketStore, useToggleView, useUpdateScene } from "../../../store/store"; +import Layer2DVisibility from "../geomentries/layers/layer2DVisibility"; +import { useFrame, useThree } from "@react-three/fiber"; +import DeletableLineorPoint from "../functions/deletableLineOrPoint"; +import removeSoloPoint from "../geomentries/points/removeSoloPoint"; +import removeReferenceLine from "../geomentries/lines/removeReferenceLine"; +import DeleteLayer from "../geomentries/layers/deleteLayer"; +import { getLines } from "../../../services/factoryBuilder/lines/getLinesApi"; +import objectLinesToArray from "../geomentries/lines/lineConvertions/objectLinesToArray"; +import loadInitialPoint from "../IntialLoad/loadInitialPoint"; +import loadInitialLine from "../IntialLoad/loadInitialLine"; +import deletePoint from "../geomentries/points/deletePoint"; +import deleteLine from "../geomentries/lines/deleteLine"; +import drawWall from "../geomentries/lines/drawWall"; +import drawOnlyFloor from "../geomentries/floors/drawOnlyFloor"; +import addDragControl from "../eventDeclaration/dragControlDeclaration"; + + +const FloorPlanGroup = ({ floorPlanGroup, floorPlanGroupLine, floorPlanGroupPoint, floorGroup, currentLayerPoint, dragPointControls, hoveredDeletablePoint, hoveredDeletableLine, plane, line, lines, onlyFloorline, onlyFloorlines, ReferenceLineMesh, LineCreated, isSnapped, ispreSnapped, snappedPoint, isSnappedUUID, isAngleSnapped, anglesnappedPoint }: any) => { + const state = useThree(); + const { scene, camera, gl, raycaster, controls } = state; + const { activeLayer, setActiveLayer } = useActiveLayer(); + const { toggleView, setToggleView } = useToggleView(); + const { deletePointOrLine, setDeletePointOrLine } = useDeletePointOrLine(); + const { toolMode, setToolMode } = useToolMode(); + const { movePoint, setMovePoint } = useMovePoint(); + const { removedLayer, setRemovedLayer } = useRemovedLayer(); + const { updateScene, setUpdateScene } = useUpdateScene(); + const { newLines, setNewLines } = useNewLines(); + const { deletedLines, setDeletedLines } = useDeletedLines(); + const { socket } = useSocketStore(); + + useEffect(() => { + addDragControl(dragPointControls, currentLayerPoint, state, floorPlanGroupPoint, floorPlanGroupLine, lines, onlyFloorlines, socket); + }, [state]); + + useEffect(() => { + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + // Load data from localStorage if available + getLines(organization).then((data) => { + + const Lines: Types.Lines = objectLinesToArray(data); + + // const data = localStorage.getItem("Lines"); + + if (Lines) { + lines.current = Lines; + loadInitialPoint(lines, floorPlanGroupPoint, currentLayerPoint, dragPointControls); + loadInitialLine(floorPlanGroupLine, lines); + setUpdateScene(true); + } + }) + }, []); + + useEffect(() => { + if (!toggleView) { + removeSoloPoint(line, floorPlanGroupLine, floorPlanGroupPoint); + removeReferenceLine(floorPlanGroup, ReferenceLineMesh, LineCreated, line); + } + }, [toggleView]); + + useEffect(() => { + if (toolMode === "Wall" || toolMode === "Floor") { + setDeletePointOrLine(false); + setMovePoint(false); + } else { + removeSoloPoint(line, floorPlanGroupLine, floorPlanGroupPoint); + removeReferenceLine(floorPlanGroup, ReferenceLineMesh, LineCreated, line); + } + }, [toolMode]); + + useEffect(() => { + if (movePoint) { + setToolMode(null); + setDeletePointOrLine(false); + if (dragPointControls.current) { + dragPointControls.current.enabled = true; + } + } else { + if (dragPointControls.current) { + dragPointControls.current.enabled = false; + } + } + }, [movePoint]); + + useEffect(() => { + if (deletePointOrLine) { + setToolMode(null); + setMovePoint(false); + } + }, [deletePointOrLine]); + + useEffect(() => { + Layer2DVisibility(activeLayer, floorPlanGroup, floorPlanGroupLine, floorPlanGroupPoint, currentLayerPoint, dragPointControls); + }, [activeLayer]); + + useEffect(() => { + if (removedLayer !== null) { + DeleteLayer(removedLayer, lines, floorPlanGroupLine, floorPlanGroupPoint, onlyFloorlines, floorGroup, setDeletedLines, setRemovedLayer, socket); + } + }, [removedLayer]); + + useEffect(() => { + + const canvasElement = gl.domElement; + + let drag = false; + let isLeftMouseDown = false; + + const onMouseDown = (evt: any) => { + if (evt.button === 0) { + isLeftMouseDown = true; + drag = false; + } + }; + + const onMouseUp = (evt: any) => { + if (evt.button === 0) { + isLeftMouseDown = false; + } + if (controls) { + (controls as any).enabled = true; + } + } + + const onMouseMove = () => { + if (isLeftMouseDown) { + drag = true; + } + }; + + const onContextMenu = (e: any) => { + e.preventDefault(); + if (toolMode === "Wall" || toolMode === "Floor") { + removeSoloPoint(line, floorPlanGroupLine, floorPlanGroupPoint); + removeReferenceLine(floorPlanGroup, ReferenceLineMesh, LineCreated, line); + } + }; + + const onMouseClick = (evt: any) => { + if (!plane.current || drag) return; + + if (deletePointOrLine) { + if (hoveredDeletablePoint.current !== null) { + deletePoint(hoveredDeletablePoint, onlyFloorlines, floorPlanGroupPoint, floorPlanGroupLine, lines, setDeletedLines, socket); + } + if (hoveredDeletableLine.current !== null) { + deleteLine(hoveredDeletableLine, onlyFloorlines, lines, floorPlanGroupLine, floorPlanGroupPoint, setDeletedLines, socket); + } + } + + if (toolMode === "Wall") { + drawWall(raycaster, plane, floorPlanGroupPoint, snappedPoint, isSnapped, isSnappedUUID, line, ispreSnapped, anglesnappedPoint, isAngleSnapped, lines, floorPlanGroupLine, floorPlanGroup, ReferenceLineMesh, LineCreated, currentLayerPoint, dragPointControls, setNewLines, setDeletedLines, activeLayer, socket); + } + + if (toolMode === "Floor") { + drawOnlyFloor(raycaster, state, camera, plane, floorPlanGroupPoint, snappedPoint, isSnapped, isSnappedUUID, line, ispreSnapped, anglesnappedPoint, isAngleSnapped, onlyFloorline, onlyFloorlines, lines, floorPlanGroupLine, floorPlanGroup, ReferenceLineMesh, LineCreated, currentLayerPoint, dragPointControls, setNewLines, setDeletedLines, activeLayer, socket); + } + } + + if (deletePointOrLine || toolMode === "Wall" || toolMode === "Floor") { + canvasElement.addEventListener("mousedown", onMouseDown); + canvasElement.addEventListener("mouseup", onMouseUp); + canvasElement.addEventListener("mousemove", onMouseMove); + canvasElement.addEventListener("click", onMouseClick); + canvasElement.addEventListener("contextmenu", onContextMenu); + } + + return () => { + canvasElement.removeEventListener("mousedown", onMouseDown); + canvasElement.removeEventListener("mouseup", onMouseUp); + canvasElement.removeEventListener("mousemove", onMouseMove); + canvasElement.removeEventListener("click", onMouseClick); + canvasElement.removeEventListener("contextmenu", onContextMenu); + }; + }, [deletePointOrLine, toolMode, activeLayer]) + + + useFrame(() => { + if (deletePointOrLine) { + DeletableLineorPoint(state, plane, floorPlanGroupLine, floorPlanGroupPoint, hoveredDeletableLine, hoveredDeletablePoint); + } + }) + + return ( + + + + + ) +} + +export default FloorPlanGroup; \ No newline at end of file diff --git a/frontend/src/components/scene/groups/wallItemsGroup.tsx b/frontend/src/components/scene/groups/wallItemsGroup.tsx new file mode 100644 index 0000000..05a1e86 --- /dev/null +++ b/frontend/src/components/scene/groups/wallItemsGroup.tsx @@ -0,0 +1,289 @@ +import { useEffect } from "react"; +import { useDeleteModels, useDeletePointOrLine, useObjectPosition, useObjectRotation, useObjectScale, useSelectedWallItem, useSocketStore, useWallItems } from "../../../store/store"; +import { Csg } from "../csg/csg"; +import * as Types from "../world/worldTypes"; +import * as CONSTANTS from "../world/worldConstants"; +import * as THREE from "three"; +import { useThree } from "@react-three/fiber"; +import handleMeshMissed from "../eventFunctions/handleMeshMissed"; +import DeleteWallItems from "../geomentries/walls/deleteWallItems"; +import loadInitialWallItems from "../IntialLoad/loadInitialWallItems"; +import AddWallItems from "../geomentries/walls/addWallItems"; + + +const WallItemsGroup = ({ currentWallItem, AssetConfigurations, hoveredDeletableWallItem, selectedItemsIndex, setSelectedItemsIndex, CSGGroup }: any) => { + const { deleteModels, setDeleteModels } = useDeleteModels(); + const { wallItems, setWallItems } = useWallItems(); + const { objectPosition, setObjectPosition } = useObjectPosition(); + const { objectScale, setObjectScale } = useObjectScale(); + const { objectRotation, setObjectRotation } = useObjectRotation(); + const { deletePointOrLine, setDeletePointOrLine } = useDeletePointOrLine(); + const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem(); + const { socket } = useSocketStore(); + const state = useThree(); + const { pointer, camera, raycaster } = state; + + + useEffect(() => { + // Load Wall Items from the backend + loadInitialWallItems(setWallItems, AssetConfigurations); + }, []); + + + ////////// Update the Scale value changes in thewallItems State ////////// + + ////////// Update the Position value changes in the selected item ////////// + + ////////// Update the Rotation value changes in the selected item ////////// + + useEffect(() => { + if (objectScale.x && objectScale.y && objectScale.z) { + let ScaledWallItems: Types.wallItems = []; + wallItems.forEach((items: any) => { + if (items.model?.uuid === currentWallItem.current?.parent?.uuid) { + items.scale = [objectScale.x, objectScale.y, objectScale.z]; + } + ScaledWallItems.push(items); + }); + setWallItems(ScaledWallItems); + } + }, [objectScale]); + + useEffect(() => { + if (objectPosition.x && objectPosition.y && objectPosition.z) { + let ScaledWallItems: Types.wallItems = []; + wallItems.forEach((items: any) => { + if (items.model?.uuid === currentWallItem.current?.parent?.uuid) { + items.position = [objectPosition.x, objectPosition.y, objectPosition.z]; + } + ScaledWallItems.push(items); + }); + setWallItems(ScaledWallItems); + } + }, [objectPosition]); + + useEffect(() => { + if (objectRotation.x && objectRotation.y && objectRotation.z) { + let ScaledWallItems: Types.wallItems = []; + wallItems.forEach((items: any) => { + if (items.model?.uuid === currentWallItem.current?.parent?.uuid) { + const radiansX = objectRotation.x * (Math.PI / 180); + const radiansY = objectRotation.y * (Math.PI / 180); + const radiansZ = objectRotation.z * (Math.PI / 180); + const quaternion = new THREE.Quaternion().setFromEuler( + new THREE.Euler(radiansX, radiansY, radiansZ) + ); + items.quaternion = [quaternion.x, quaternion.y, quaternion.z, quaternion.w]; + } + ScaledWallItems.push(items); + }); + setWallItems(ScaledWallItems); + } + }, [objectRotation]); + + useEffect(() => { + const canvasElement = state.gl.domElement; + function handlePointerMove(e: any) { + if (selectedItemsIndex !== null && !deletePointOrLine && e.buttons === 1) { + const Raycaster = state.raycaster; + const intersects = Raycaster.intersectObjects(CSGGroup.current?.children[0].children!, true); + const Object = intersects.find((child) => child.object.name.includes("WallRaycastReference")); + + if (Object) { + (state.controls as any)!.enabled = false; + setWallItems((prevItems: any) => { + const updatedItems = [...prevItems]; + let position: [number, number, number] = [0, 0, 0]; + + if (updatedItems[selectedItemsIndex].type === "Fixed-Move") { + position = [Object!.point.x, Math.floor(Object!.point.y / CONSTANTS.wallConfig.height) * CONSTANTS.wallConfig.height, Object!.point.z]; + } else if (updatedItems[selectedItemsIndex].type === "Free-Move") { + position = [Object!.point.x, Object!.point.y, Object!.point.z]; + } + + requestAnimationFrame(() => { + setObjectPosition(new THREE.Vector3(...position)); + setObjectRotation({ + x: THREE.MathUtils.radToDeg(Object!.object.rotation.x), + y: THREE.MathUtils.radToDeg(Object!.object.rotation.y), + z: THREE.MathUtils.radToDeg(Object!.object.rotation.z), + }); + }); + + updatedItems[selectedItemsIndex] = { + ...updatedItems[selectedItemsIndex], + position: position, + quaternion: Object!.object.quaternion.clone() as Types.QuaternionType, + }; + + return updatedItems; + }); + } + } + } + + async function handlePointerUp() { + const Raycaster = state.raycaster; + const intersects = Raycaster.intersectObjects(CSGGroup.current?.children[0].children!, true); + const Object = intersects.find((child) => child.object.name.includes("WallRaycastReference")); + if (Object) { + if (selectedItemsIndex !== null) { + let currentItem: any = null; + setWallItems((prevItems: any) => { + const updatedItems = [...prevItems]; + const WallItemsForStorage = updatedItems.map((item) => { + const { model, ...rest } = item; + return { + ...rest, + modeluuid: model?.uuid, + }; + }); + + currentItem = updatedItems[selectedItemsIndex]; + localStorage.setItem("WallItems", JSON.stringify(WallItemsForStorage)); + return updatedItems; + }); + + setTimeout(async () => { + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // await setWallItem( + // organization, + // currentItem?.model?.uuid, + // currentItem.modelname, + // currentItem.type!, + // currentItem.csgposition!, + // currentItem.csgscale!, + // currentItem.position, + // currentItem.quaternion, + // currentItem.scale!, + // ) + + //SOCKET + + const data = { + organization: organization, + modeluuid: currentItem.model?.uuid!, + modelname: currentItem.modelname!, + type: currentItem.type!, + csgposition: currentItem.csgposition!, + csgscale: currentItem.csgscale!, + position: currentItem.position!, + quaternion: currentItem.quaternion, + scale: currentItem.scale!, + socketId: socket.id + } + + socket.emit('v1:wallItems:set', data); + }, 0); + (state.controls as any)!.enabled = true; + } + } + } + + canvasElement.addEventListener("pointermove", handlePointerMove); + canvasElement.addEventListener("pointerup", handlePointerUp); + + return () => { + canvasElement.removeEventListener("pointermove", handlePointerMove); + canvasElement.removeEventListener("pointerup", handlePointerUp); + }; + }, [selectedItemsIndex]); + + useEffect(() => { + const canvasElement = state.gl.domElement; + let drag = false; + let isLeftMouseDown = false; + + const onMouseDown = (evt: any) => { + if (evt.button === 0) { + isLeftMouseDown = true; + drag = false; + } + }; + + const onMouseUp = (evt: any) => { + if (evt.button === 0) { + isLeftMouseDown = false; + if (!drag && deleteModels) { + DeleteWallItems(hoveredDeletableWallItem, setWallItems, wallItems, socket); + } + } + }; + + const onMouseMove = () => { + if (isLeftMouseDown) { + drag = true; + } + }; + + const onDrop = (event: any) => { + + if (!event.dataTransfer?.files[0]) return + pointer.x = (event.clientX / window.innerWidth) * 2 - 1; + pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; + raycaster.setFromCamera(pointer, camera); + + if (AssetConfigurations[(event.dataTransfer.files[0].name.split('.'))[0]]) { + const selected = (event.dataTransfer.files[0].name.split('.'))[0]; + + if (AssetConfigurations[selected]?.type) { + AddWallItems(selected, raycaster, CSGGroup, AssetConfigurations, setWallItems, socket); + } + event.preventDefault(); + } + } + + const onDragOver = (event: any) => { + event.preventDefault(); + }; + + canvasElement.addEventListener("mousedown", onMouseDown); + canvasElement.addEventListener("mouseup", onMouseUp); + canvasElement.addEventListener("mousemove", onMouseMove); + canvasElement.addEventListener("drop", onDrop); + canvasElement.addEventListener("dragover", onDragOver); + + return () => { + canvasElement.removeEventListener("mousedown", onMouseDown); + canvasElement.removeEventListener("mouseup", onMouseUp); + canvasElement.removeEventListener("mousemove", onMouseMove); + canvasElement.removeEventListener("drop", onDrop); + canvasElement.removeEventListener("dragover", onDragOver); + }; + }, [deleteModels, wallItems]) + + useEffect(() => { + if (deleteModels) { + handleMeshMissed(currentWallItem, setSelectedWallItem, setSelectedItemsIndex); + setSelectedWallItem(null); + setSelectedItemsIndex(null); + } + }, [deleteModels]) + + return ( + <> + {wallItems.map((item: Types.WallItem, index: number) => ( + + + + ))} + + ) +} + +export default WallItemsGroup; \ No newline at end of file diff --git a/frontend/src/components/scene/groups/wallsAndWallItems.tsx b/frontend/src/components/scene/groups/wallsAndWallItems.tsx new file mode 100644 index 0000000..a4e7d71 --- /dev/null +++ b/frontend/src/components/scene/groups/wallsAndWallItems.tsx @@ -0,0 +1,56 @@ +import { Geometry } from "@react-three/csg"; +import { useDeleteModels, useSelectedWallItem, useToggleView, useTransformMode, useWallItems, useWalls } from "../../../store/store"; +import handleMeshDown from "../eventFunctions/handleMeshDown"; +import handleMeshMissed from "../eventFunctions/handleMeshMissed"; +import WallsMesh from "./wallsMesh"; +import WallItemsGroup from "./wallItemsGroup"; +import { useEffect } from "react"; + + +const WallsAndWallItems = ({ CSGGroup, AssetConfigurations, setSelectedItemsIndex, selectedItemsIndex, currentWallItem, csg, lines, hoveredDeletableWallItem }: any) => { + const { walls, setWalls } = useWalls(); + const { wallItems, setWallItems } = useWallItems(); + const { toggleView, setToggleView } = useToggleView(); + const { deleteModels, setDeleteModels } = useDeleteModels(); + const { transformMode, setTransformMode } = useTransformMode(); + const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem(); + + useEffect(() => { + if (transformMode === null) { + if (!deleteModels) { + handleMeshMissed(currentWallItem, setSelectedWallItem, setSelectedItemsIndex); + setSelectedWallItem(null); + setSelectedItemsIndex(null); + } + } + }, [transformMode]) + + return ( + { + if (!deleteModels && transformMode !== null) { + handleMeshDown(event, currentWallItem, setSelectedWallItem, setSelectedItemsIndex, wallItems, toggleView); + } + }} + onPointerMissed={() => { + if (!deleteModels) { + handleMeshMissed(currentWallItem, setSelectedWallItem, setSelectedItemsIndex); + setSelectedWallItem(null); + setSelectedItemsIndex(null); + } + }} + > + + + + + + ) +} + +export default WallsAndWallItems; \ No newline at end of file diff --git a/frontend/src/components/scene/groups/wallsMesh.tsx b/frontend/src/components/scene/groups/wallsMesh.tsx new file mode 100644 index 0000000..aa3fb38 --- /dev/null +++ b/frontend/src/components/scene/groups/wallsMesh.tsx @@ -0,0 +1,65 @@ +import * as THREE from 'three'; +import * as Types from '../world/worldTypes'; +import * as CONSTANTS from '../world/worldConstants'; +import { Base } from '@react-three/csg'; +import { MeshDiscardMaterial } from '@react-three/drei'; +import { useUpdateScene, useWalls } from '../../../store/store'; +import { useEffect } from 'react'; +import { getLines } from '../../../services/factoryBuilder/lines/getLinesApi'; +import objectLinesToArray from '../geomentries/lines/lineConvertions/objectLinesToArray'; +import loadWalls from '../geomentries/walls/loadWalls'; + +const WallsMesh = ({ lines }: any) => { + const { walls, setWalls } = useWalls(); + const { updateScene, setUpdateScene } = useUpdateScene(); + + useEffect(() => { + if (updateScene) { + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + getLines(organization).then((data) => { + const Lines: Types.Lines = objectLinesToArray(data); + localStorage.setItem("Lines", JSON.stringify(Lines)); + + if (Lines) { + loadWalls(lines, setWalls); + } + }) + setUpdateScene(false); + } + }, [updateScene]) + + return ( + <> + {walls.map((wall: Types.Wall, index: number) => ( + + + + + + + + + ))} + + ) +} + +export default WallsMesh; \ No newline at end of file diff --git a/frontend/src/components/scene/groups/zoneGroup.tsx b/frontend/src/components/scene/groups/zoneGroup.tsx new file mode 100644 index 0000000..d50d8a6 --- /dev/null +++ b/frontend/src/components/scene/groups/zoneGroup.tsx @@ -0,0 +1,245 @@ +import { useEffect } from "react"; +import * as THREE from 'three'; +import * as Types from '../world/worldTypes'; +import * as CONSTANTS from "../world/worldConstants"; +import { useActiveLayer, useSocketStore, useDeleteModels, useDeletePointOrLine, useMovePoint, useToggleView, useUpdateScene, useNewLines, useToolMode } from "../../../store/store"; +import { useThree } from "@react-three/fiber"; +import arrayLineToObject from "../geomentries/lines/lineConvertions/arrayLineToObject"; +import addPointToScene from "../geomentries/points/addPointToScene"; +import addLineToScene from "../geomentries/lines/addLineToScene"; +import removeSoloPoint from "../geomentries/points/removeSoloPoint"; +import removeReferenceLine from "../geomentries/lines/removeReferenceLine"; +import getClosestIntersection from "../geomentries/lines/getClosestIntersection"; +import loadZones from "../geomentries/zones/loadZones"; + +const ZoneGroup = ({ zoneGroup, plane, floorPlanGroupLine, floorPlanGroupPoint, line, lines, currentLayerPoint, dragPointControls, floorPlanGroup, ReferenceLineMesh, LineCreated, isSnapped, ispreSnapped, snappedPoint, isSnappedUUID, isAngleSnapped, anglesnappedPoint }: any) => { + const { toggleView, setToggleView } = useToggleView(); + const { deleteModels, setDeleteModels } = useDeleteModels(); + const { deletePointOrLine, setDeletePointOrLine } = useDeletePointOrLine(); + const { toolMode, setToolMode } = useToolMode(); + const { movePoint, setMovePoint } = useMovePoint(); + const { socket } = useSocketStore(); + const { activeLayer } = useActiveLayer(); + const { gl, raycaster, camera, pointer } = useThree(); + const { updateScene, setUpdateScene } = useUpdateScene(); + const { newLines, setNewLines } = useNewLines(); + + useEffect(() => { + if (updateScene) { + loadZones(lines, zoneGroup); + setUpdateScene(false); + } + }, [updateScene]) + + useEffect(() => { + if (toolMode === "Zone") { + setDeletePointOrLine(false); + setMovePoint(false); + setDeleteModels(false); + } else { + removeSoloPoint(line, floorPlanGroupLine, floorPlanGroupPoint); + removeReferenceLine(floorPlanGroup, ReferenceLineMesh, LineCreated, line); + } + }, [toolMode]) + + useEffect(() => { + + const canvasElement = gl.domElement; + + let drag = false; + let isLeftMouseDown = false; + + const onMouseDown = (evt: any) => { + if (evt.button === 0) { + isLeftMouseDown = true; + drag = false; + } + }; + + const onMouseUp = (evt: any) => { + if (evt.button === 0) { + isLeftMouseDown = false; + } + } + + const onMouseMove = () => { + if (isLeftMouseDown) { + drag = true; + } + }; + + const onContextMenu = (e: any) => { + e.preventDefault(); + if (toolMode === "Zone") { + removeSoloPoint(line, floorPlanGroupLine, floorPlanGroupPoint); + removeReferenceLine(floorPlanGroup, ReferenceLineMesh, LineCreated, line); + } + }; + + const onMouseClick = (evt: any) => { + if (!plane.current || drag) return; + const intersects = raycaster.intersectObject(plane.current, true); + let intersectionPoint = intersects[0].point; + const points = floorPlanGroupPoint.current?.children ?? []; + const intersectsPoint = raycaster.intersectObjects(points, true).find(intersect => intersect.object.visible); + let intersectsLines: any = raycaster.intersectObjects(floorPlanGroupLine.current.children, true); + + if (intersectsLines.length > 0 && intersects && intersects.length > 0 && !intersectsPoint) { + const lineType = intersectsLines[0].object.userData.linePoints[0][3]; + if (lineType === CONSTANTS.lineConfig.zoneName) { + // console.log("intersected a zone line"); + + const ThroughPoint = (intersectsLines[0].object.geometry.parameters.path).getPoints(300); + let intersection = getClosestIntersection(ThroughPoint, intersectionPoint); + if (!intersection) return; + const point = addPointToScene(intersection, CONSTANTS.pointConfig.zoneOuterColor, currentLayerPoint, floorPlanGroupPoint, dragPointControls, undefined, CONSTANTS.lineConfig.zoneName); + (line.current as Types.Line).push([new THREE.Vector3(intersection.x, 0.01, intersection.z), point.uuid, activeLayer, CONSTANTS.lineConfig.zoneName,]); + if (line.current.length >= 2 && line.current[0] && line.current[1]) { + lines.current.push(line.current as Types.Line); + + const data = arrayLineToObject(line.current as Types.Line); + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // setLine(organization, data.layer!, data.line!, data.type!); + + //SOCKET + + const input = { + organization: organization, + layer: data.layer, + line: data.line, + type: data.type, + socketId: socket.id + } + + socket.emit('v1:Line:create', input); + + setNewLines([line.current]); + + addLineToScene(line.current[0][0], line.current[1][0], CONSTANTS.lineConfig.zoneColor, line.current, floorPlanGroupLine); + let lastPoint = line.current[line.current.length - 1]; + line.current = [lastPoint]; + } + } + } else if (intersectsPoint && intersects && intersects.length > 0) { + if (intersectsPoint.object.userData.type === CONSTANTS.lineConfig.zoneName) { + // console.log("intersected a zone point"); + + intersectionPoint = intersectsPoint.object.position; + (line.current as Types.Line).push([new THREE.Vector3(intersectionPoint.x, 0.01, intersectionPoint.z), intersectsPoint.object.uuid, activeLayer, CONSTANTS.lineConfig.zoneName]); + if (line.current.length >= 2 && line.current[0] && line.current[1]) { + lines.current.push(line.current as Types.Line); + + const data = arrayLineToObject(line.current as Types.Line); + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // setLine(organization, data.layer!, data.line!, data.type!); + + //SOCKET + + const input = { + organization: organization, + layer: data.layer, + line: data.line, + type: data.type, + socketId: socket.id + } + + socket.emit('v1:Line:create', input); + + setNewLines([line.current]); + + addLineToScene(line.current[0][0], line.current[1][0], CONSTANTS.lineConfig.zoneColor, line.current, floorPlanGroupLine); + let lastPoint = line.current[line.current.length - 1]; + line.current = [lastPoint]; + ispreSnapped.current = false; + isSnapped.current = false; + } + } + } else if (intersects && intersects.length > 0) { + // console.log("intersected a empty area"); + + let uuid: string = ""; + if (isAngleSnapped.current && anglesnappedPoint.current && line.current.length > 0) { + intersectionPoint = anglesnappedPoint.current; + const point = addPointToScene(intersectionPoint, CONSTANTS.pointConfig.zoneOuterColor, currentLayerPoint, floorPlanGroupPoint, dragPointControls, undefined, CONSTANTS.lineConfig.zoneName); + uuid = point.uuid; + } else if (isSnapped.current && snappedPoint.current && line.current.length > 0) { + intersectionPoint = snappedPoint.current; + uuid = isSnappedUUID.current!; + } else if (ispreSnapped.current && snappedPoint.current) { + intersectionPoint = snappedPoint.current; + uuid = isSnappedUUID.current!; + } else { + const point = addPointToScene(intersectionPoint, CONSTANTS.pointConfig.zoneOuterColor, currentLayerPoint, floorPlanGroupPoint, dragPointControls, undefined, CONSTANTS.lineConfig.zoneName); + uuid = point.uuid; + } + + (line.current as Types.Line).push([new THREE.Vector3(intersectionPoint.x, 0.01, intersectionPoint.z), uuid, activeLayer, CONSTANTS.lineConfig.zoneName]); + if (line.current.length >= 2 && line.current[0] && line.current[1]) { + lines.current.push(line.current as Types.Line); + + const data = arrayLineToObject(line.current as Types.Line); + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // setLine(organization, data.layer!, data.line!, data.type!); + + //SOCKET + + const input = { + organization: organization, + layer: data.layer, + line: data.line, + type: data.type, + socketId: socket.id + } + + socket.emit('v1:Line:create', input); + + setNewLines([line.current]); + + addLineToScene(line.current[0][0], line.current[1][0], CONSTANTS.lineConfig.zoneColor, line.current, floorPlanGroupLine); + let lastPoint = line.current[line.current.length - 1]; + line.current = [lastPoint]; + ispreSnapped.current = false; + isSnapped.current = false; + } + } + } + + if (toolMode === 'Zone') { + canvasElement.addEventListener("mousedown", onMouseDown); + canvasElement.addEventListener("mouseup", onMouseUp); + canvasElement.addEventListener("mousemove", onMouseMove); + canvasElement.addEventListener("click", onMouseClick); + canvasElement.addEventListener("contextmenu", onContextMenu); + } + + return () => { + canvasElement.removeEventListener("mousedown", onMouseDown); + canvasElement.removeEventListener("mouseup", onMouseUp); + canvasElement.removeEventListener("mousemove", onMouseMove); + canvasElement.removeEventListener("click", onMouseClick); + canvasElement.removeEventListener("contextmenu", onContextMenu); + }; + }, [toolMode]) + + return ( + + + ) +} + +export default ZoneGroup; \ No newline at end of file diff --git a/frontend/src/components/scene/indexDB/idbUtils.ts b/frontend/src/components/scene/indexDB/idbUtils.ts new file mode 100644 index 0000000..bc7c30d --- /dev/null +++ b/frontend/src/components/scene/indexDB/idbUtils.ts @@ -0,0 +1,45 @@ +const DB_NAME = 'GLTFStorage'; +const STORE_NAME = 'models'; +const DB_VERSION = 1; + +export function initializeDB(): Promise { + return new Promise((resolve, reject) => { + const request = indexedDB.open(DB_NAME, DB_VERSION); + + request.onupgradeneeded = () => { + const db = request.result; + if (!db.objectStoreNames.contains(STORE_NAME)) { + db.createObjectStore(STORE_NAME); + } + }; + + request.onsuccess = () => resolve(request.result); + request.onerror = () => reject(request.error); + }); +} + +export async function storeGLTF(key: string, file: Blob): Promise { + const db = await initializeDB(); + + return new Promise((resolve, reject) => { + const transaction = db.transaction(STORE_NAME, 'readwrite'); + const store = transaction.objectStore(STORE_NAME); + const request = store.put(file, key); + + request.onsuccess = () => resolve(); + request.onerror = () => reject(request.error); + }); +} + +export async function retrieveGLTF(key: string): Promise { + const db = await initializeDB(); + + return new Promise((resolve, reject) => { + const transaction = db.transaction(STORE_NAME, 'readonly'); + const store = transaction.objectStore(STORE_NAME); + const request = store.get(key); + + request.onsuccess = () => resolve(request.result as Blob | undefined); + request.onerror = () => reject(request.error); + }); +} \ No newline at end of file diff --git a/frontend/src/components/scene/mqttTemp/drieHtmlTemp.tsx b/frontend/src/components/scene/mqttTemp/drieHtmlTemp.tsx new file mode 100644 index 0000000..44f326c --- /dev/null +++ b/frontend/src/components/scene/mqttTemp/drieHtmlTemp.tsx @@ -0,0 +1,109 @@ +import { Html } from "@react-three/drei"; +import * as THREE from "three"; +import * as Types from "../world/worldTypes"; +import { useDrieTemp, useDrieUIValue } from "../../../store/store" +import UI from "./ui"; +import { useEffect } from "react"; +import { useThree } from "@react-three/fiber"; + +export default function DrieHtmlTemp({ itemsGroup }: { itemsGroup: Types.RefGroup }) { + const { drieTemp, setDrieTemp } = useDrieTemp(); + const { drieUIValue, setDrieUIValue } = useDrieUIValue(); + const state = useThree(); + const { camera, raycaster } = state; + + useEffect(() => { + const canvasElement = state.gl.domElement; + let drag = false; + let isLeftMouseDown = false; + + const onMouseDown = (evt: any) => { + if (evt.button === 0) { + isLeftMouseDown = true; + drag = false; + } + }; + + const onMouseMove = () => { + if (isLeftMouseDown) { + drag = true; + } + }; + + const onMouseUp = (evt: any) => { + if (evt.button === 0) { + isLeftMouseDown = false; + if (drag) return; + if (!itemsGroup.current) return + let intersects = raycaster.intersectObjects(itemsGroup.current.children, true); + if (intersects.length > 0) { + let currentObject = intersects[0].object; + + while (currentObject) { + if (currentObject.name === "Scene") { + break; + } + currentObject = currentObject.parent as THREE.Object3D; + } + if (currentObject && (currentObject.userData.name === "SV2 Controll pannel" || currentObject.userData.name === "forklift")) { + const worldPos = new THREE.Vector3(); + currentObject.getWorldPosition(worldPos); + + const rightOffset = new THREE.Vector3(1, 0, 0); + const upOffset = new THREE.Vector3(0, 1, 0); + + currentObject.localToWorld(rightOffset); + currentObject.localToWorld(upOffset); + + const finalPosition = worldPos.clone().addScaledVector(rightOffset.sub(currentObject.position).normalize(), 2.5).addScaledVector(upOffset.sub(currentObject.position).normalize(), 2.3); + + setDrieTemp(finalPosition); + } else { + setDrieTemp(undefined); + } + } + else { + setDrieTemp(undefined); + } + } + }; + + + canvasElement.addEventListener("mousedown", onMouseDown); + canvasElement.addEventListener("mouseup", onMouseUp); + canvasElement.addEventListener("mousemove", onMouseMove); + + return () => { + canvasElement.removeEventListener("mousedown", onMouseDown); + canvasElement.removeEventListener("mouseup", onMouseUp); + canvasElement.removeEventListener("mousemove", onMouseMove); + }; + }, []) + + return ( + <> + {drieTemp && + + + + + + } + + ) +} \ No newline at end of file diff --git a/frontend/src/components/scene/mqttTemp/ui.jsx b/frontend/src/components/scene/mqttTemp/ui.jsx new file mode 100644 index 0000000..cafff38 --- /dev/null +++ b/frontend/src/components/scene/mqttTemp/ui.jsx @@ -0,0 +1,141 @@ +export default function UI({ temperature, humidity, touch, header }) { + return ( +
+
+ {header ? header : "Sensor Details"} +
+
+
+
+ + + + + +
+
+ Temperature +
+
+ {temperature} +
+
+
+
+ + + + + +
+
+ Humidity +
+
+ {humidity} +
+
+
+
+
+
+ Touch Sensor +
+
+ {touch === "True" ? "Active" : "In active"} +
+
+
+
+ ); +} diff --git a/frontend/src/components/scene/postProcessing/postProcessing.tsx b/frontend/src/components/scene/postProcessing/postProcessing.tsx new file mode 100644 index 0000000..58cb671 --- /dev/null +++ b/frontend/src/components/scene/postProcessing/postProcessing.tsx @@ -0,0 +1,79 @@ +import * as THREE from 'three' +import { EffectComposer, N8AO, Outline } from '@react-three/postprocessing' +import { BlendFunction } from 'postprocessing' +import { useDeletableFloorItem, useSelectedWallItem, useselectedFloorItem } from '../../../store/store'; +import * as Types from '../world/worldTypes' +import * as CONSTANTS from '../world/worldConstants'; + +export default function PostProcessing() { + const { deletableFloorItem, setDeletableFloorItem } = useDeletableFloorItem(); + const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem(); + const { selectedFloorItem, setselectedFloorItem } = useselectedFloorItem(); + + function flattenChildren(children: any[]) { + const allChildren: any[] = []; + children.forEach(child => { + allChildren.push(child); + if (child.children && child.children.length > 0) { + allChildren.push(...flattenChildren(child.children)); + } + }); + return allChildren; + } + + return ( + <> + + + {deletableFloorItem && + + } + {selectedWallItem && + child.name !== "CSG_REF" + ) + } + selectionLayer={10} + width={3000} + blendFunction={BlendFunction.ALPHA} + edgeStrength={5} + resolutionScale={2} + pulseSpeed={0} + visibleEdgeColor={CONSTANTS.outlineConfig.assetSelectColor} + hiddenEdgeColor={CONSTANTS.outlineConfig.assetSelectColor} + blur={true} + xRay={true} + />} + {selectedFloorItem && + + } + + + ) +} \ No newline at end of file diff --git a/frontend/src/components/scene/scene.tsx b/frontend/src/components/scene/scene.tsx new file mode 100644 index 0000000..bfb1458 --- /dev/null +++ b/frontend/src/components/scene/scene.tsx @@ -0,0 +1,50 @@ +import { useMemo } from "react"; +import * as THREE from "three"; +import { Canvas } from "@react-three/fiber"; +import { Environment, KeyboardControls } from "@react-three/drei"; + +import World from "./world/world"; +import Controls from "./controls/controls"; +import TransformControl from "./controls/transformControls"; +import PostProcessing from "./postProcessing/postProcessing" +import Sun from "./environment/sky"; +import CamModelsGroup from "./collab/collabCams"; +import Shadows from "./environment/shadow"; +import MqttEvents from "../../services/factoryBuilder/mqtt/mqttEvents"; + +import background from "../../assets/textures/hdr/mudroadpuresky2k.hdr"; +import SelectionControls from "./controls/selection/selectionControls"; +import MeasurementTool from "./tools/measurementTool"; + +export default function App() { + + const map = useMemo(() => [ + { name: "forward", keys: ["ArrowUp", "w", "W"] }, + { name: "backward", keys: ["ArrowDown", "s", "S"] }, + { name: "left", keys: ["ArrowLeft", "a", "A"] }, + { name: "right", keys: ["ArrowRight", "d", "D"] }, + // { name: "jump", keys: ["Space"] }, + ], []) + + return ( + + + + + + + + + + + + + + + + ); +} diff --git a/frontend/src/components/scene/tools/measurementTool.tsx b/frontend/src/components/scene/tools/measurementTool.tsx new file mode 100644 index 0000000..8930df2 --- /dev/null +++ b/frontend/src/components/scene/tools/measurementTool.tsx @@ -0,0 +1,191 @@ +import * as THREE from 'three'; +import { useEffect, useRef, useState } from 'react'; +import { useThree, useFrame } from '@react-three/fiber'; +import { useToolMode } from '../../../store/store'; +import { Html } from '@react-three/drei'; + +const MeasurementTool = () => { + const { gl, raycaster, pointer, camera, scene } = useThree(); + const { toolMode } = useToolMode(); + + const [points, setPoints] = useState([]); + const [tubeGeometry, setTubeGeometry] = useState(null); + const groupRef = useRef(null); + const [startConePosition, setStartConePosition] = useState(null); + const [endConePosition, setEndConePosition] = useState(null); + const [startConeQuaternion, setStartConeQuaternion] = useState(new THREE.Quaternion()); + const [endConeQuaternion, setEndConeQuaternion] = useState(new THREE.Quaternion()); + const [coneSize, setConeSize] = useState({ radius: 0.2, height: 0.5 }); + + + const MIN_RADIUS = 0.001, MAX_RADIUS = 0.1; + const MIN_CONE_RADIUS = 0.01, MAX_CONE_RADIUS = 0.4; + const MIN_CONE_HEIGHT = 0.035, MAX_CONE_HEIGHT = 2.0; + + useEffect(() => { + const canvasElement = gl.domElement; + let drag = false; + let isLeftMouseDown = false; + + const onMouseDown = () => { + isLeftMouseDown = true; + drag = false; + }; + + const onMouseUp = (evt: any) => { + isLeftMouseDown = false; + if (evt.button === 0 && !drag) { + raycaster.setFromCamera(pointer, camera); + const intersects = raycaster.intersectObjects(scene.children, true) + .filter(intersect => !intersect.object.name.includes("Roof") && !intersect.object.name.includes("MeasurementReference")); + + if (intersects.length > 0) { + const intersectionPoint = intersects[0].point.clone(); + if (points.length < 2) { + setPoints([...points, intersectionPoint]); + } else { + setPoints([intersectionPoint]); + } + } + } + }; + + const onMouseMove = () => { + if (isLeftMouseDown) drag = true; + }; + + const onContextMenu = (evt: any) => { + if (!drag) { + evt.preventDefault(); + setPoints([]); + setTubeGeometry(null); + } + }; + + if (toolMode === "MeasurementScale") { + canvasElement.addEventListener("pointerdown", onMouseDown); + canvasElement.addEventListener("pointermove", onMouseMove); + canvasElement.addEventListener("pointerup", onMouseUp); + canvasElement.addEventListener("contextmenu", onContextMenu); + } else { + resetMeasurement(); + setPoints([]); + } + + return () => { + canvasElement.removeEventListener("pointerdown", onMouseDown); + canvasElement.removeEventListener("pointermove", onMouseMove); + canvasElement.removeEventListener("pointerup", onMouseUp); + canvasElement.removeEventListener("contextmenu", onContextMenu); + }; + }, [toolMode, camera, raycaster, pointer, scene, points]); + + useFrame(() => { + if (points.length === 1) { + raycaster.setFromCamera(pointer, camera); + const intersects = raycaster.intersectObjects(scene.children, true) + .filter(intersect => !intersect.object.name.includes("Roof") && !intersect.object.name.includes("MeasurementReference")); + + if (intersects.length > 0) { + updateMeasurement(points[0], intersects[0].point); + } + } else if (points.length === 2) { + updateMeasurement(points[0], points[1]); + } else { + resetMeasurement(); + } + }); + + const updateMeasurement = (start: THREE.Vector3, end: THREE.Vector3) => { + const distance = start.distanceTo(end); + + const radius = THREE.MathUtils.clamp(distance * 0.02, MIN_RADIUS, MAX_RADIUS); + const coneRadius = THREE.MathUtils.clamp(distance * 0.05, MIN_CONE_RADIUS, MAX_CONE_RADIUS); + const coneHeight = THREE.MathUtils.clamp(distance * 0.2, MIN_CONE_HEIGHT, MAX_CONE_HEIGHT); + + setConeSize({ radius: coneRadius, height: coneHeight }); + + const direction = new THREE.Vector3().subVectors(end, start).normalize(); + + const offset = direction.clone().multiplyScalar(coneHeight * 0.5); + + let tubeStart = start.clone().add(offset); + let tubeEnd = end.clone().sub(offset); + + tubeStart.y = Math.max(tubeStart.y, 0); + tubeEnd.y = Math.max(tubeEnd.y, 0); + + const curve = new THREE.CatmullRomCurve3([tubeStart, tubeEnd]); + setTubeGeometry(new THREE.TubeGeometry(curve, 20, radius, 8, false)); + + setStartConePosition(tubeStart); + setEndConePosition(tubeEnd); + setStartConeQuaternion(getArrowOrientation(start, end)); + setEndConeQuaternion(getArrowOrientation(end, start)); + }; + + const resetMeasurement = () => { + setTubeGeometry(null); + setStartConePosition(null); + setEndConePosition(null); + }; + + const getArrowOrientation = (start: THREE.Vector3, end: THREE.Vector3) => { + const direction = new THREE.Vector3().subVectors(end, start).normalize().negate(); + const quaternion = new THREE.Quaternion(); + quaternion.setFromUnitVectors(new THREE.Vector3(0, 1, 0), direction); + return quaternion; + }; + + useEffect(() => { + if (points.length === 2) { + console.log(points[0].distanceTo(points[1])); + } + }, [points]) + + return ( + + {startConePosition && ( + + + + + )} + {endConePosition && ( + + + + + )} + {tubeGeometry && ( + + + + )} + + {startConePosition && endConePosition && ( + +
{startConePosition.distanceTo(endConePosition).toFixed(2)} m
+ + )} +
+ ); + +}; + +export default MeasurementTool; diff --git a/frontend/src/components/scene/world/world.tsx b/frontend/src/components/scene/world/world.tsx new file mode 100644 index 0000000..a1c247c --- /dev/null +++ b/frontend/src/components/scene/world/world.tsx @@ -0,0 +1,336 @@ +////////// Three and React Three Fiber Imports ////////// + +import * as THREE from "three"; +import { useEffect, useRef, useState } from "react"; +import { useThree, useFrame } from "@react-three/fiber"; + +////////// Component Imports ////////// + +import DistanceText from "../../3d-ui/distanceText"; +import ReferenceDistanceText from "../../3d-ui/referenceDistanceText"; + +////////// Assests Imports ////////// + +import arch from "../../../assets/models/gltf-glb/arch.glb"; +import door from "../../../assets/models/gltf-glb/door.glb"; +import Window from "../../../assets/models/gltf-glb/window.glb"; + +////////// Zustand State Imports ////////// + +import { + useToggleView, + useDeletePointOrLine, + useMovePoint, + useActiveLayer, + useSocketStore, + useWallVisibility, + useRoofVisibility, + useShadows, + useUpdateScene, + useWalls, + useToolMode +} from "../../../store/store"; + +////////// 3D Function Imports ////////// + +import loadWalls from "../geomentries/walls/loadWalls"; + +import * as Types from "./worldTypes"; + +import SocketResponses from "../collab/socketResponses.dev"; +import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; +import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader"; +import FloorItemsGroup from "../groups/floorItemsGroup"; +import FloorPlanGroup from "../groups/floorPlanGroup"; +import FloorGroup from "../groups/floorGroup"; +import FloorGroupAilse from "../groups/floorGroupAisle"; +import Draw from "../functions/draw"; +import WallsAndWallItems from "../groups/wallsAndWallItems"; +import Ground from "../environment/ground"; +import ZoneGroup from "../groups/zoneGroup"; +import { findEnvironment } from "../../../services/factoryBuilder/environment/findEnvironment"; +import Layer2DVisibility from "../geomentries/layers/layer2DVisibility"; +import DrieHtmlTemp from "../mqttTemp/drieHtmlTemp"; +import AnimationSample from "../animation/animationSample"; + +export default function World() { + const state = useThree(); // Importing the state from the useThree hook, which contains the scene, camera, and other Three.js elements. + const csg = useRef(); // Reference for CSG object, used for 3D modeling. + const CSGGroup = useRef() as Types.RefMesh; // Reference to a group of CSG objects. + const scene = useRef() as Types.RefScene; // Reference to the scene. + const camera = useRef() as Types.RefCamera; // Reference to the camera object. + const controls = useRef(); // Reference to the controls object. + const raycaster = useRef() as Types.RefRaycaster; // Reference for raycaster used for detecting objects being pointed at in the scene. + const dragPointControls = useRef() as Types.RefDragControl; // Reference for drag point controls, an array for drag control. + + // Assigning the scene and camera from the Three.js state to the references. + + scene.current = state.scene; + camera.current = state.camera; + controls.current = state.controls; + raycaster.current = state.raycaster; + + const plane = useRef(null); // Reference for a plane object for raycaster reference. + const grid = useRef() as any; // Reference for a grid object for raycaster reference. + const snappedPoint = useRef() as Types.RefVector3; // Reference for storing a snapped point at the (end = isSnapped) and (start = ispreSnapped) of the line. + const isSnapped = useRef(false) as Types.RefBoolean; // Boolean reference to indicate if an object is snapped at the (end). + const anglesnappedPoint = useRef() as Types.RefVector3; // Reference for storing an angle-snapped point when the line is in 90 degree etc... + const isAngleSnapped = useRef(false) as Types.RefBoolean; // Boolean to indicate if angle snapping is active. + const isSnappedUUID = useRef() as Types.RefString; // UUID reference to identify the snapped point. + const ispreSnapped = useRef(false) as Types.RefBoolean; // Boolean reference to indicate if an object is snapped at the (start). + const tempLoader = useRef() as Types.RefMesh; // Reference for a temporary loader for the floor items. + const isTempLoader = useRef() as Types.RefBoolean; // Reference to check if a temporary loader is active. + const Tube = useRef() as Types.RefTubeGeometry; // Reference for tubes used for reference line creation and updation. + const line = useRef([]) as Types.RefLine; // Reference for line which stores the current line that is being drawn. + const lines = useRef([]) as Types.RefLines; // Reference for lines which stores all the lines that are ever drawn. + const onlyFloorline = useRef([]); // Reference for floor lines which does not have walls or roof and have only floor used to store the current line that is being drawn. + const onlyFloorlines = useRef([]); // Reference for all the floor lines that are ever drawn. + const ReferenceLineMesh = useRef() as Types.RefMesh; // Reference for storing the mesh of the reference line for moving it during draw. + const LineCreated = useRef(false) as Types.RefBoolean; // Boolean to track whether the reference line is created or not. + const referencePole = useRef() as Types.RefMesh; // Reference for a pole that is used as the reference for the user to show where it is placed. + const itemsGroup = useRef() as Types.RefGroup; // Reference to the THREE.Group that has the floor items (Gltf). + const floorGroup = useRef() as Types.RefGroup; // Reference to the THREE.Group that has the roofs and the floors. + const AttachedObject = useRef() as Types.RefMesh; // Reference for an object that is attached using dbl click for transform controls rotation. + const floorPlanGroup = useRef() as Types.RefGroup; // Reference for a THREE.Group that has the lines group and the points group. + const floorPlanGroupLine = useRef() as Types.RefGroup; // Reference for a THREE.Group that has the lines that are drawn. + const floorPlanGroupPoint = useRef() as Types.RefGroup; // Reference for a THREE.Group that has the points that are created. + const floorGroupAisle = useRef() as Types.RefGroup; + const zoneGroup = useRef() as Types.RefGroup; + const currentLayerPoint = useRef([]) as Types.RefMeshArray; // Reference for points that re in the current layer used to update the points in drag controls. + const hoveredDeletablePoint = useRef() as Types.RefMesh; // Reference for the currently hovered point that can be deleted. + const hoveredDeletableLine = useRef() as Types.RefMesh; // Reference for the currently hovered line that can be deleted. + const hoveredDeletableFloorItem = useRef() as Types.RefMesh; // Reference for the currently hovered floor item that can be deleted. + const hoveredDeletableWallItem = useRef() as Types.RefMesh; // Reference for the currently hovered wall item that can be deleted. + const hoveredDeletablePillar = useRef() as Types.RefMesh; // Reference for the currently hovered pillar that can be deleted. + const currentWallItem = useRef() as Types.RefMesh; // Reference for the currently selected wall item that can be scaled, dragged etc... + + const cursorPosition = new THREE.Vector3(); // 3D vector for storing the cursor position. + + const [selectedItemsIndex, setSelectedItemsIndex] = useState(null); // State for tracking the index of the selected item. + const { activeLayer, setActiveLayer } = useActiveLayer(); // State that changes based on which layer the user chooses in Layers.jsx. + const { toggleView, setToggleView } = useToggleView(); // State for toggling between 2D and 3D. + const { toolMode, setToolMode } = useToolMode(); + const { movePoint, setMovePoint } = useMovePoint(); // State that stores a boolean which represents whether the move mode is active or not. + const { deletePointOrLine, setDeletePointOrLine } = useDeletePointOrLine(); + const { socket } = useSocketStore(); + const { roofVisibility, setRoofVisibility } = useRoofVisibility(); + const { wallVisibility, setWallVisibility } = useWallVisibility(); + const { shadows, setShadows } = useShadows(); + const { updateScene, setUpdateScene } = useUpdateScene(); + const { walls, setWalls } = useWalls(); + const [RefTextupdate, setRefTextUpdate] = useState(-1000); + + + // const loader = new GLTFLoader(); + // const dracoLoader = new DRACOLoader(); + + // dracoLoader.setDecoderPath('https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/'); + // loader.setDRACOLoader(dracoLoader); + + ////////// Assest Configuration Values ////////// + + const AssetConfigurations: Types.AssetConfigurations = { + arch: { + modelUrl: arch, + scale: [0.75, 0.75, 0.75], + csgscale: [2, 4, 0.5], + csgposition: [0, 2, 0], + positionY: () => 0, + type: "Fixed-Move", + }, + door: { + modelUrl: door, + scale: [0.75, 0.75, 0.75], + csgscale: [2, 4, 0.5], + csgposition: [0, 2, 0], + positionY: () => 0, + type: "Fixed-Move", + }, + window: { + modelUrl: Window, + scale: [0.75, 0.75, 0.75], + csgscale: [5, 3, 0.5], + csgposition: [0, 1.5, 0], + positionY: (intersectionPoint) => intersectionPoint.point.y, + type: "Free-Move", + }, + }; + + ////////// All Toggle's ////////// + + useEffect(() => { + setRefTextUpdate((prevUpdate) => prevUpdate - 1); + if (dragPointControls.current) { + dragPointControls.current.enabled = false; + } + if (toggleView) { + Layer2DVisibility(activeLayer, floorPlanGroup, floorPlanGroupLine, floorPlanGroupPoint, currentLayerPoint, dragPointControls); + } else { + setToolMode(null); + setDeletePointOrLine(false); + setMovePoint(false); + loadWalls(lines, setWalls); + setUpdateScene(true); + line.current = []; + } + }, [toggleView]); + + useEffect(() => { + THREE.Cache.clear(); + THREE.Cache.enabled = true; + }, []); + + useEffect(() => { + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + async function fetchVisibility() { + const visibility = await findEnvironment(organization, localStorage.getItem('userId')!); + if (visibility) { + setRoofVisibility(visibility.roofVisibility); + setWallVisibility(visibility.wallVisibility); + setShadows(visibility.shadowVisibility); + } + } + fetchVisibility(); + }, []) + + ////////// UseFrame is Here ////////// + + useFrame(() => { + if (toolMode) { + Draw(state, plane, cursorPosition, floorPlanGroupPoint, floorPlanGroupLine, snappedPoint, isSnapped, isSnappedUUID, line, lines, ispreSnapped, floorPlanGroup, ReferenceLineMesh, LineCreated, setRefTextUpdate, Tube, anglesnappedPoint, isAngleSnapped, toolMode) + } + }); + + ////////// Return ////////// + + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + ); +} \ No newline at end of file diff --git a/frontend/src/components/scene/world/worldConstants.ts b/frontend/src/components/scene/world/worldConstants.ts new file mode 100644 index 0000000..ce5cacd --- /dev/null +++ b/frontend/src/components/scene/world/worldConstants.ts @@ -0,0 +1,384 @@ +export type Controls = { + azimuthRotateSpeed: number; + polarRotateSpeed: number; + truckSpeed: number; + minDistance: number; + maxDistance: number; + maxPolarAngle: number; + leftMouse: number; + forwardSpeed: number; + backwardSpeed: number; + leftSpeed: number; + rightSpeed: number; +}; + +export type ThirdPersonControls = { + azimuthRotateSpeed: number; + polarRotateSpeed: number; + truckSpeed: number; + maxDistance: number; + maxPolarAngle: number; + minZoom: number; + maxZoom: number; + targetOffset: number; + cameraHeight: number; + leftMouse: number; + rightMouse: number; + wheelMouse: number; + middleMouse: number; +}; + +export type ControlsTransition = { + leftMouse: number; + rightMouse: number; + wheelMouse: number; + middleMouse: number; +}; + +export type TwoDimension = { + defaultPosition: [x: number, y: number, z: number]; + defaultTarget: [x: number, y: number, z: number]; + defaultAzimuth: number; + minDistance: number; + leftMouse: number; + rightMouse: number; +}; + +export type ThreeDimension = { + defaultPosition: [x: number, y: number, z: number]; + defaultTarget: [x: number, y: number, z: number]; + defaultRotation: [x: number, y: number, z: number]; + defaultAzimuth: number; + boundaryBottom: [x: number, y: number, z: number]; + boundaryTop: [x: number, y: number, z: number]; + minDistance: number; + leftMouse: number; + rightMouse: number; +}; + + +export type GridConfig = { + size: number; + divisions: number; + primaryColor: string; + secondaryColor: string; + + position2D: [x: number, y: number, z: number]; + position3D: [x: number, y: number, z: number]; +} + +export type PlaneConfig = { + position2D: [x: number, y: number, z: number]; + position3D: [x: number, y: number, z: number]; + rotation: number; + + width: number; + height: number; + color: string; +} + +export type ShadowConfig = { + shadowOffset: number, + + shadowmapSizewidth: number, + shadowmapSizeheight: number, + shadowcamerafar: number, + shadowcameranear: number, + shadowcameratop: number, + shadowcamerabottom: number, + shadowcameraleft: number, + shadowcameraright: number, + shadowbias: number, + shadownormalBias: number, + + shadowMaterialPosition: [x: number, y: number, z: number], + shadowMaterialRotation: [x: number, y: number, z: number], + + shadowMaterialOpacity: number, +} + +export type SkyConfig = { + defaultTurbidity: number; + maxTurbidity: number; + minTurbidity: number; + defaultRayleigh: number; + mieCoefficient: number; + mieDirectionalG: number; + skyDistance: number; +} + +export type AssetConfig = { + defaultScaleBeforeGsap: [number, number, number]; + defaultScaleAfterGsap: [number, number, number]; +} + +export type PointConfig = { + defaultInnerColor: string; + defaultOuterColor: string; + deleteColor: string; + boxScale: [number, number, number]; + + wallOuterColor: string; + floorOuterColor: string; + aisleOuterColor: string; + zoneOuterColor: string; + + snappingThreshold: number; +} + +export type LineConfig = { + tubularSegments: number; + radius: number; + radialSegments: number; + + wallName: string; + floorName: string; + aisleName: string; + zoneName: string; + referenceName: string; + + lineIntersectionPoints: number; + + defaultColor: string; + + wallColor: string; + floorColor: string; + aisleColor: string; + zoneColor: string; + helperColor: string; +} + +export type WallConfig = { + defaultColor: string; + height: number; + width: number; +} + +export type FloorConfig = { + defaultColor: string; + height: number; + + textureScale: number; +} + +export type RoofConfig = { + defaultColor: string; + height: number; +} + +export type AisleConfig = { + width: number; + height: number; + + defaultColor: number; +} + +export type ZoneConfig = { + defaultColor: string; + + color: string; +} + +export type ColumnConfig = { + defaultColor: string; +} + +export type OutlineConfig = { + assetSelectColor: number; + assetDeleteColor: number; +} + + + + +export const firstPersonControls: Controls = { + azimuthRotateSpeed: 0.3, // Speed of rotation around the azimuth axis + polarRotateSpeed: 0.3, // Speed of rotation around the polar axis + truckSpeed: 10, // Speed of truck movement + minDistance: 0, // Minimum distance from the target + maxDistance: 0, // Maximum distance from the target + maxPolarAngle: Math.PI, // Maximum polar angle + + leftMouse: 1, // Mouse button for rotation (ROTATE) + + forwardSpeed: 0.3, // Speed of forward movement + backwardSpeed: -0.3, // Speed of backward movement + leftSpeed: -0.3, // Speed of left movement + rightSpeed: 0.3, // Speed of right movement +}; + +export const thirdPersonControls: ThirdPersonControls = { + azimuthRotateSpeed: 1, // Speed of rotation around the azimuth axis + polarRotateSpeed: 1, // Speed of rotation around the polar axis + truckSpeed: 2, // Speed of truck movement + maxDistance: 100, // Maximum distance from the target + maxPolarAngle: Math.PI / 2 - 0.05, // Maximum polar angle + minZoom: 6, // Minimum zoom level + maxZoom: 21, // Maximum zoom level + targetOffset: 20, // Offset of the target from the camera + cameraHeight: 30, // Height of the camera + leftMouse: 2, // Mouse button for panning + rightMouse: 1, // Mouse button for rotation + wheelMouse: 8, // Mouse button for zooming + middleMouse: 8, // Mouse button for zooming +}; + +export const controlsTransition: ControlsTransition = { + leftMouse: 0, // Mouse button for no action + rightMouse: 0, // Mouse button for no action + wheelMouse: 0, // Mouse button for no action + middleMouse: 0, // Mouse button for no action +}; + +export const twoDimension: TwoDimension = { + defaultPosition: [0, 100, 0], // Default position of the camera + defaultTarget: [0, 0, 0], // Default target of the camera + defaultAzimuth: 0, // Default azimuth of the camera + minDistance: 25, // Minimum distance from the target + leftMouse: 2, // Mouse button for panning + rightMouse: 0, // Mouse button for no action +}; + +export const threeDimension: ThreeDimension = { + defaultPosition: [0, 40, 30], // Default position of the camera + defaultTarget: [0, 0, 0], // Default target of the camera + defaultRotation: [0, 0, 0], // Default rotation of the camera + defaultAzimuth: 0, // Default azimuth of the camera + boundaryBottom: [-150, 0, -150], // Bottom boundary of the camera movement + boundaryTop: [150, 100, 150], // Top boundary of the camera movement + minDistance: 1, // Minimum distance from the target + leftMouse: 2, // Mouse button for panning + rightMouse: 1, // Mouse button for rotation +}; + +export const camPositionUpdateInterval: number = 200; // Interval for updating the camera position + +export const gridConfig: GridConfig = { + size: 300, // Size of the grid + divisions: 75, // Number of divisions in the grid + primaryColor: "#d5d5d5", // Primary color of the grid + secondaryColor: "#e3e3e3", // Secondary color of the grid + + position2D: [0, 0.1, 0], // Position of the grid in 2D view + position3D: [0, -0.5, 0], // Position of the grid in 3D view +} + +export const planeConfig: PlaneConfig = { + position2D: [0, -0.5, 0], // Position of the plane + position3D: [0, -0.65, 0], // Position of the plane + rotation: -Math.PI / 2, // Rotation of the plane + + width: 300, // Width of the plane + height: 300, // Height of the plane + color: "white" // Color of the plane +} + +export const shadowConfig: ShadowConfig = { + shadowOffset: 50, // Offset of the shadow + + shadowmapSizewidth: 1024, // Width of the shadow map + shadowmapSizeheight: 1024, // Height of the shadow map + // shadowmapSizewidth: 8192, // Width of the shadow map + // shadowmapSizeheight: 8192, // Height of the shadow map + shadowcamerafar: 70, // Far plane of the shadow camera + shadowcameranear: 0.1, // Near plane of the shadow camera + shadowcameratop: 30, // Top plane of the shadow camera + shadowcamerabottom: -30, // Bottom plane of the shadow camera + shadowcameraleft: -30, // Left plane of the shadow camera + shadowcameraright: 30, // Right plane of the shadow camera + shadowbias: -0.001, // Bias of the shadow + shadownormalBias: 0.02, // Normal bias of the shadow + + shadowMaterialPosition: [0, 0.01, 0], // Position of the shadow material + shadowMaterialRotation: [-Math.PI / 2, 0, 0], // Rotation of the shadow material + + shadowMaterialOpacity: 0.1 // Opacity of the shadow material +} + +export const skyConfig: SkyConfig = { + defaultTurbidity: 10.0, // Default turbidity of the sky + maxTurbidity: 20.0, // Maximum turbidity of the sky + minTurbidity: 0.0, // Minimum turbidity of the sky + defaultRayleigh: 1.9, // Default Rayleigh scattering coefficient + mieCoefficient: 0.1, // Mie scattering coefficient + mieDirectionalG: 1.0, // Mie directional G + skyDistance: 2000 // Distance of the sky +} + +export const assetConfig: AssetConfig = { + defaultScaleBeforeGsap: [0.1, 0.1, 0.1], // Default scale of the assets + defaultScaleAfterGsap: [1, 1, 1] // Default scale of the assets +} + +export const pointConfig: PointConfig = { + defaultInnerColor: "#ffffff", // Default inner color of the points + defaultOuterColor: "#ffffff", // Default outer color of the points + deleteColor: "#ff0000", // Color of the points when deleting + boxScale: [0.5, 0.5, 0.5], // Scale of the points + + wallOuterColor: "#C7C7C7", // Outer color of the wall points + floorOuterColor: "#808080", // Outer color of the floor points + aisleOuterColor: "#FBBC05", // Outer color of the aisle points + zoneOuterColor: "#007BFF", // Outer color of the zone points + + snappingThreshold: 1, // Threshold for snapping +} + +export const lineConfig: LineConfig = { + tubularSegments: 64, // Number of tubular segments + radius: 0.15, // Radius of the lines + radialSegments: 8, // Number of radial segments + + wallName: "WallLine", // Name of the wall lines + floorName: "FloorLine", // Name of the floor lines + aisleName: "AisleLine", // Name of the aisle lines + zoneName: "ZoneLine", // Name of the zone lines + referenceName: "ReferenceLine", // Name of the reference lines + + lineIntersectionPoints: 300, // Number of intersection points + + defaultColor: "#000000", // Default color of the lines + + wallColor: "#C7C7C7", // Color of the wall lines + floorColor: "#808080", // Color of the floor lines + aisleColor: "#FBBC05", // Color of the aisle lines + zoneColor: "#007BFF", // Color of the zone lines + helperColor: "#C164FF" // Color of the helper lines +} + +export const wallConfig: WallConfig = { + defaultColor: "white", // Default color of the walls + height: 7, // Height of the walls + width: 0.05, // Width of the walls +} + +export const floorConfig: FloorConfig = { + defaultColor: "grey", // Default color of the floors + height: 0.1, // Height of the floors + textureScale: 0.1, // Scale of the floor texture +} + +export const roofConfig: RoofConfig = { + defaultColor: "grey", // Default color of the roofs + height: 0.1 // Height of the roofs +} + +export const aisleConfig: AisleConfig = { + width: 0.1, // Width of the aisles + height: 0.01, // Height of the aisles + defaultColor: 0xffff00 // Default color of the aisles +} + +export const zoneConfig: ZoneConfig = { + defaultColor: "black", // Default color of the zones + color: "blue" // Color of the zones +} + +export const columnConfig: ColumnConfig = { + defaultColor: "White", // Default color of the columns +} + +export const outlineConfig: OutlineConfig = { + assetSelectColor: 0x0054fE, // Color of the selected assets + assetDeleteColor: 0xFF0000 // Color of the deleted assets +} \ No newline at end of file diff --git a/frontend/src/components/scene/world/worldTypes.d.ts b/frontend/src/components/scene/world/worldTypes.d.ts new file mode 100644 index 0000000..32293d9 --- /dev/null +++ b/frontend/src/components/scene/world/worldTypes.d.ts @@ -0,0 +1,271 @@ +// Importing core classes and types from THREE.js and @react-three/fiber +import * as THREE from "three"; +import { TransformControls } from 'three/examples/jsm/controls/TransformControls'; +import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; +import { DragControls } from 'three/examples/jsm/controls/DragControls'; +import { IntersectionEvent } from '@react-three/fiber/dist/declarations/src/core/events'; +import { ThreeEvent } from "@react-three/fiber/dist/declarations/src/core/events"; +import { RootState } from "@react-three/fiber"; +import { CSM } from "three/examples/jsm/csm/CSM"; +import { CSMHelper } from 'three/examples/jsm/csm/CSMHelper'; +import { CameraControls } from "@react-three/drei"; + +/** Core THREE.js and React-Fiber Event Types **/ + +// Event type specific to pointer events in @react-three/fiber +export type ThreeEvent = ThreeEvent; + + +/** Vector and Reference Types **/ + +// 2D Vector type from THREE.js +export type Vector2 = THREE.Vector2; + +// React ref for a mutable 2D vector, useful for tracking changes over time +export type RefVector2 = React.MutableRefObject; + +// 3D Vector type from THREE.js +export type Vector3 = THREE.Vector3; + +// Mutable reference for 3D vectors, allowing for dynamic scene changes +export type RefVector3 = React.MutableRefObject; + +// Quaternion type for rotations, using the base structure from THREE.js +export type QuaternionType = THREE.QuaternionLike; + + +/** Basic Object Types for Scene Management **/ + +// THREE.js mesh object +export type Mesh = THREE.Mesh; + +// Color type allowing various formats (hex, RGB, string, etc.) +export type Color = THREE.Color | string | number; + +// Shape type for defining custom geometries +export type Shape = THREE.Shape; + +// Event type for intersections within the scene +export type IntersectionEvent = THREE.Intersection; + +// Array type for intersections with objects in the scene +export type IntersectsType = THREE.Intersection>[]; + +// Event type for mesh interactions +export type MeshEvent = IntersectionEvent; + +// Event type for drag interactions +export type DragEvent = DragEvent; + +// Generic type for user data attached to objects +export type UserData = any; + + +/** React Mutable References for Scene Objects **/ + +// Mutable reference to the scene, used in React-based projects +export type RefScene = React.MutableRefObject; + +// THREE.js group type for grouping objects +export type Group = THREE.Group; + +// Mutable reference for groups, supporting updates in React components +export type RefGroup = React.MutableRefObject; + +// Reference type for meshes, allowing null or undefined values +export type RefMesh = React.MutableRefObject; + +// Mutable reference to camera controls +export type RefControls = React.MutableRefObject; + +// Control types for transformation controls in the scene +export type TransformControl = TransformControl; +export type RefTransformControl = React.MutableRefObject; + +// Array of mesh references for tracking multiple meshes +export type RefMeshArray = React.MutableRefObject; + +// Array of 3D vectors, useful for handling points or positions +export type Vector3Array = THREE.Vector3[]; + +// Drag control type, either a valid DragControls instance or null +export type DragControl = DragControls | null; +export type RefDragControl = React.MutableRefObject; + + +/** Primitive Types with Mutable References **/ + +export type String = string; +export type RefStringArray = React.MutableRefObject; +export type RefString = React.MutableRefObject; + +export type Boolean = boolean; +export type RefBoolean = React.MutableRefObject; + +export type Number = number; +export type NumberArray = number[]; + +// Reference for the THREE.js Raycaster, useful in handling ray intersections +export type RefRaycaster = React.MutableRefObject; + +// Camera reference, supporting both perspective and basic cameras +export type RefCamera = React.MutableRefObject; + + +/** Three.js Root State Management **/ + +// Root state of the @react-three/fiber instance, providing context of the scene +export type ThreeState = RootState; + + +/** Point and Line Types for Spatial Geometry **/ + +// Defines a point in 3D space with metadata for unique identification +export type Point = [THREE.Vector3, string, number, string]; + +// Defines a line as two connected points, commonly used in scene building +export type Line = [Point, Point]; + +// Reference for a line, allowing dynamic updates +export type RefLine = React.MutableRefObject; + +// Collection of lines for structured geometry +export type Lines = Array; + + +/** Wall and Room Types for 3D Space Management **/ + +// Defines a wall with its geometry, position, rotation, material, and layer information +export type Wall = [THREE.ExtrudeGeometry, [number, number, number], [number, number, number], string, number]; + +// Collection of walls, useful in scene construction +export type Walls = Array; + +// Reference type for walls, allowing dynamic updates in React +export type RefWalls = React.MutableRefObject; + +// Room type, containing coordinates and layer metadata for spatial management +export type Rooms = Array<{ coordinates: Array<{ position: THREE.Vector3, uuid: string }>, layer: number }>; + +// Reference for room objects, enabling updates within React components +export type RefRooms = React.MutableRefObject, layer: number }>>; + +// Reference for lines, supporting React-based state changes +export type RefLines = React.MutableRefObject; + + +/** Floor Line Types for Layered Structures **/ + +// Floor line type for single lines on the floor level +export type OnlyFloorLine = Array; + +// Reference for floor lines, allowing manipulation in React +export type RefOnlyFloorLine = React.MutableRefObject; + +// Collection of lines across multiple floors, for multi-level structures +export type OnlyFloorLines = Array; + +// Reference for multi-level floor lines, allowing structured updates +export type RefOnlyFloorLines = React.MutableRefObject; + + +/** GeoJSON Line Integration **/ + +// Structure for representing GeoJSON lines, integrating external data sources +export type GeoJsonLine = { + line: any; + uuids: [string, string]; + layer: number; + type: string; +}; + + +/** State Management Types for React Components **/ + +// Dispatch types for number and boolean states, commonly used in React hooks +export type NumberIncrementState = React.Dispatch>; +export type BooleanState = React.Dispatch>; + +// Mutable reference for TubeGeometry, allowing dynamic geometry updates +export type RefTubeGeometry = React.MutableRefObject; + + +/** Floor Item Configuration **/ + +// Type for individual items placed on the floor, with positioning and rotation metadata +export type FloorItemType = { + modeluuid: string; + modelname: string; + position: [number, number, number]; + rotation: { x: number; y: number; z: number }; + modelfileID?: string; + isLocked: boolean; + isVisible: boolean; +}; + +// Array of floor items for managing multiple objects on the floor +export type FloorItems = Array; + +// Dispatch type for setting floor item state in React +export type setFloorItemSetState = React.Dispatch>; + + +/** Asset Configuration for Loading and Positioning **/ + +// Configuration for assets, allowing model URLs, scaling, positioning, and types +interface AssetConfiguration { + modelUrl: string; + scale?: [number, number, number]; + csgscale?: [number, number, number]; + csgposition?: [number, number, number]; + positionY?: (intersectionPoint: { point: THREE.Vector3 }) => number; + type?: "Fixed-Move" | "Free-Move"; +} + +// Collection of asset configurations, keyed by unique identifiers +export type AssetConfigurations = { + [key: string]: AssetConfiguration; +}; + + +/** Wall Item Configuration **/ + +// Configuration for wall items, including model, scale, position, and rotation +interface WallItem { + type: "Fixed-Move" | "Free-Move" | undefined; + model?: THREE.Group; + modeluuid?: string + modelname?: string; + scale?: [number, number, number]; + csgscale?: [number, number, number]; + csgposition?: [number, number, number]; + position?: [number, number, number]; + quaternion?: Types.QuaternionType; +} + +// Collection of wall items, allowing for multiple items in a scene +export type wallItems = Array; + +// Dispatch for setting wall item state in React +export type setWallItemSetState = React.Dispatch>; + +// Dispatch for setting vector3 state in React +export type setVector3State = React.Dispatch>; + +// Dispatch for setting euler state in React +export type setEulerState = React.Dispatch>; + +// Reference type for wall items, allowing direct access to the mutable array +export type RefWallItems = React.MutableRefObject; + + +/** Wall and Item Selection State Management **/ + +// State management for selecting, removing, and indexing wall items +export type setRemoveLayerSetState = (layer: number | null) => void; +export type setSelectedWallItemSetState = (item: THREE.Object3D | null) => void; +export type setSelectedFloorItemSetState = (item: THREE.Object3D | null) => void; +export type setSelectedItemsIndexSetState = (index: number | null) => void; + +export type RefCSM = React.MutableRefObject; +export type RefCSMHelper = React.MutableRefObject; \ No newline at end of file diff --git a/frontend/src/components/templates/modals/conformationPopup.tsx b/frontend/src/components/templates/modals/conformationPopup.tsx new file mode 100644 index 0000000..36c7529 --- /dev/null +++ b/frontend/src/components/templates/modals/conformationPopup.tsx @@ -0,0 +1,31 @@ +import RenderOverlay from "../overlay"; + +interface ModalProps { + onClose: () => void; +} + +const ConfirmationPopup = ({ onClose }: ModalProps) => { + return ( + // renders its children in a separate layer (typically for modals or overlays) + + {/* Modal overlay that listens for clicks to close the popup */} +
+
{ + // Stops click events from propagating to the overlay, preventing accidental closure when clicking inside the modal + e.stopPropagation(); + }} + > + {/* Modal header or title */} +
Modal Title
+ {/* Modal content */} +
+
+
+
+ // End of overlay rendering + ); +}; + +export default ConfirmationPopup; diff --git a/frontend/src/components/templates/overlay.tsx b/frontend/src/components/templates/overlay.tsx new file mode 100644 index 0000000..b0d9d4e --- /dev/null +++ b/frontend/src/components/templates/overlay.tsx @@ -0,0 +1,21 @@ +import { ReactNode } from "react"; +import ReactDOM from "react-dom"; + +// Define the props interface for the component, which requires `children` as a ReactNode type +interface PortalProps { + children: ReactNode; +} + +// The `RenderOverlay` component allows rendering of its children into a specific DOM node (`root-over`) outside of the regular React component tree +const RenderOverlay = ({ children }: PortalProps) => { + // Retrieve the DOM element with the id `root-over` which serves as the mounting point for the overlay content. + const rootOver = document.getElementById("root-over"); + + // If the `rootOver` element exists in the DOM, use `ReactDOM.createPortal` to render the `children` inside this element + // `ReactDOM.createPortal` allows rendering outside of the usual React component tree, useful for overlays, modals, and tooltips + // If `rootOver` is null (i.e., does not exist), return null, rendering nothing + return rootOver ? ReactDOM.createPortal(children, rootOver) : null; +}; + +// Export the `RenderOverlay` component as the default export for use in other parts of the application +export default RenderOverlay; diff --git a/frontend/src/components/ui/contextMenu/contextMenu.tsx b/frontend/src/components/ui/contextMenu/contextMenu.tsx new file mode 100644 index 0000000..435b24d --- /dev/null +++ b/frontend/src/components/ui/contextMenu/contextMenu.tsx @@ -0,0 +1,114 @@ +import React, { useState, useEffect } from "react"; +import { + DeleteIcon, + FlipIcon, + FlipIcon2, + FlipIcon3, + FocusIcon, + FreeIcon, + GroupIcon, + RenameIcon, + SetOrginIcon, +} from "../../../assets/images/svgExports"; +import OuterClick from "../../../utils/outerClick"; +import HandleDivs from "../../../utils/contextmenuHandler"; + +import { useToggleView, useMenuVisible } from "../../../store/store"; + +interface ContextMenuProps { + switchesRef: React.RefObject; +} + +const ContextMenu: React.FC = ({ switchesRef }) => { + const { toggleView, setToggleView } = useToggleView(); + const { menuVisible, setMenuVisible } = useMenuVisible(); + const [menuTopPosition, setMenuTopPosition] = useState(0); + const [menuLeftPosition, setMenuLeftPosition] = useState(0); + + return ( +
+ {!toggleView && menuVisible && ( +
+
+
+ +
+ Flip to X axis +
+
+
+ +
+ Flip to Y axis +
+
+
+ +
+ Flip to Z axis +
+
+
+ +
+ Rename +
+
+
+ +
+ Isolate +
+
+
+ +
+ Set origin +
+
+
+ +
+ Focus +
+
+
+ +
+ Group +
+
+
+ +
+ Delete +
+
+ )} + + +
+ ); +}; +export default ContextMenu; diff --git a/frontend/src/components/ui/inputs/dropDown.tsx b/frontend/src/components/ui/inputs/dropDown.tsx new file mode 100644 index 0000000..19212db --- /dev/null +++ b/frontend/src/components/ui/inputs/dropDown.tsx @@ -0,0 +1,106 @@ +import React, { useState } from "react"; +import { + DeleteIcon, + DropDownIcon, + EyeIcon, + LockIcon, + StarIcon, +} from "../../../assets/images/svgExports"; + +interface DropDownProps { + options: string[]; + value: string; + onChange?: (newValue: string) => void; +} + +const DropDown: React.FC = ({ options, value, onChange }) => { + const [isOpen, setIsOpen] = useState(false); + const [selectedValue, setSelectedValue] = useState(value); + const [checkedOptions, setCheckedOptions] = useState<{ + [key: string]: boolean; + }>({}); + const [starredOptions, setStarredOptions] = useState<{ + [key: string]: boolean; + }>({}); + + const toggleDropdown = () => setIsOpen(!isOpen); + + const handleOptionClick = (option: string) => { + setSelectedValue(option); + setIsOpen(false); + if (onChange) { + onChange(option); + } + }; + + const handleCheckboxClick = (option: string, event: React.MouseEvent) => { + event.stopPropagation(); // Prevents the click from propagating to the parent
  • + setCheckedOptions((prev) => ({ + ...prev, + [option]: !prev[option], // Toggle the checked state + })); + }; + + const handleStarClick = (option: string, event: React.MouseEvent) => { + event.stopPropagation(); // Prevents the click from propagating to the parent
  • + setStarredOptions((prev) => ({ + ...prev, + [option]: !prev[option], // Toggle the starred state + })); + }; + + return ( +
    +
    + {selectedValue} + {/* Use the renamed component */} +
    + {isOpen && ( +
      +
      +
      Layers
      +
      +
      +
      + {options.map((option, index) => ( +
    • handleOptionClick(option)} + > +
      + handleStarClick(option, event)}> + {" "} + {/* Red fill for starred */} + + handleCheckboxClick(option, event)} // Handle checkbox click + /> + {option} +
      + {option === selectedValue && ( +
      +
      + +
      +
      + +
      +
      + +
      +
      + )} +
    • + ))} +
    + )} +
    + ); +}; + +export default DropDown; diff --git a/frontend/src/components/ui/inputs/objectInputs.tsx b/frontend/src/components/ui/inputs/objectInputs.tsx new file mode 100644 index 0000000..e39d5c8 --- /dev/null +++ b/frontend/src/components/ui/inputs/objectInputs.tsx @@ -0,0 +1,425 @@ +import * as THREE from "three"; +import React, { useState, useEffect, useCallback } from "react"; +import { LockIcon } from "../../../assets/images/svgExports"; + +import * as Types from "../../scene/world/worldTypes" + +import { + useObjectPosition, + useObjectScale, + useObjectRotation, + useSelectedWallItem, + useselectedFloorItem, + useWallItems, + useSocketStore, + useFloorItems +} from "../../../store/store"; +import { setFloorItemApi } from "../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi"; +import { setWallItem } from "../../../services/factoryBuilder/assest/wallAsset/setWallItemApi"; + +interface ObjectInputsProps { + header: "Position" | "Scale" | "Rotation"; +} + +type Axis = "x" | "y" | "z"; + +interface AxisConfig { + axis: Axis; + initialValue: number; +} + +type WallItem = { + model: THREE.Group; + scale: number[]; + position: number[]; + quaternion: number[]; + // Add other properties as needed +}; + +const axisConfigs: AxisConfig[] = [ + { axis: "x", initialValue: 0 }, + { axis: "y", initialValue: 0 }, + { axis: "z", initialValue: 0 }, +]; + +const ObjectInputs: React.FC = ({ header }) => { + const initialLockState = axisConfigs.reduce((acc, { axis }) => { + acc[axis] = false; + return acc; + }, {} as Record); + + const [isLocked, setIsLocked] = useState(initialLockState); + const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem(); + const { selectedFloorItem, setselectedFloorItem } = useselectedFloorItem(); + const { wallItems, setWallItems } = useWallItems(); + const { objectPosition, setObjectPosition } = useObjectPosition(); + const { objectScale, setObjectScale } = useObjectScale(); + const { objectRotation, setObjectRotation } = useObjectRotation(); + const { floorItems, setFloorItems } = useFloorItems(); + const { socket } = useSocketStore(); + + useEffect(() => { + if (selectedWallItem) { + setObjectPosition(selectedWallItem.parent.position); + setObjectScale(selectedWallItem.parent.scale); + setObjectRotation({ + x: THREE.MathUtils.radToDeg(selectedWallItem.parent.rotation.x), + y: THREE.MathUtils.radToDeg(selectedWallItem.parent.rotation.y), + z: THREE.MathUtils.radToDeg(selectedWallItem.parent.rotation.z), + }); + } else if (selectedFloorItem) { + setObjectPosition(selectedFloorItem.position); + setObjectScale(selectedFloorItem.scale); + setObjectRotation({ + x: THREE.MathUtils.radToDeg(selectedFloorItem.rotation.x), + y: THREE.MathUtils.radToDeg(selectedFloorItem.rotation.y), + z: THREE.MathUtils.radToDeg(selectedFloorItem.rotation.z), + }); + } else { + setObjectPosition({ x: undefined, y: undefined, z: undefined }); + setObjectScale({ x: undefined, y: undefined, z: undefined }); + setObjectRotation({ x: undefined, y: undefined, z: undefined }); + } + }, [selectedWallItem, selectedFloorItem]); + + const handleInputChange = useCallback( + (axis: Axis, event: React.ChangeEvent) => { + if (!isLocked[axis]) { + const newValue = event.target.value === "" ? undefined : Number(event.target.value); + const currentValues = getValues() || { x: 1, y: 1, z: 1 }; + const updatedValues = { x: currentValues.x ?? 0, y: currentValues.y ?? 0, z: currentValues.z ?? 0, [axis]: newValue ?? 0 }; + + if (selectedWallItem) { + if (header === "Position") { + setObjectPosition(updatedValues); + selectedWallItem.position.set(updatedValues.x, updatedValues.y, updatedValues.z); + let MovedWallItems: WallItem[] = []; + wallItems.forEach(async (items: Types.WallItem) => { + if (items.model?.parent?.uuid === selectedWallItem.uuid) { + items.position = [updatedValues.x, updatedValues.y, updatedValues.z]; + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // await setWallItem( + // organization, + // items.model?.uuid!, + // items.modelname!, + // items.type!, + // items.csgposition!, + // items.csgscale!, + // [updatedValues.x, updatedValues.y, updatedValues.z], + // items.quaternion, + // items.scale!, + // ) + + //SOCKET + + const data = { + organization: organization, + modeluuid: items.model?.uuid!, + modelname: items.modelname!, + type: items.type!, + csgposition: items.csgposition!, + csgscale: items.csgscale!, + position: [updatedValues.x, updatedValues.y, updatedValues.z], + quaternion: items.quaternion, + scale: items.scale!, + socketId: socket.id + } + + socket.emit('v1:wallItems:set', data); + } + MovedWallItems.push(items as any); + }); + + const WallItemsForStorage = MovedWallItems.map((item) => { + const { model, ...rest } = item; + return { + ...rest, + modeluuid: model?.uuid, + }; + }); + localStorage.setItem("WallItems", JSON.stringify(WallItemsForStorage)); + } else if (header === "Scale") { + setObjectScale(updatedValues); + selectedWallItem.scale.set(updatedValues.x, updatedValues.y, updatedValues.z); + let ScaledWallItems: WallItem[] = []; + wallItems.forEach(async (items: Types.WallItem) => { + if (items.model?.parent?.uuid === selectedWallItem.uuid) { + items.scale = [updatedValues.x, updatedValues.y, updatedValues.z]; + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // await setWallItem( + // organization", + // items.model?.uuid!, + // items.modelname!, + // items.type!, + // items.csgposition!, + // items.csgscale!, + // items.position!, + // items.quaternion, + // [updatedValues.x, updatedValues.y, updatedValues.z], + // ) + + //SOCKET + + const data = { + organization: organization, + modeluuid: items.model?.uuid!, + modelname: items.modelname!, + type: items.type!, + csgposition: items.csgposition!, + csgscale: items.csgscale!, + position: items.position!, + quaternion: items.quaternion, + scale: [updatedValues.x, updatedValues.y, updatedValues.z], + socketId: socket.id + } + + socket.emit('v1:wallItems:set', data); + } + ScaledWallItems.push(items as any); + }); + + const WallItemsForStorage = ScaledWallItems.map((item) => { + const { model, ...rest } = item; + return { + ...rest, + modeluuid: model?.uuid, + }; + }); + localStorage.setItem("WallItems", JSON.stringify(WallItemsForStorage)); + } else if (header === "Rotation") { + setObjectRotation(updatedValues); + const radiansX = updatedValues.x * (Math.PI / 180); + const radiansY = updatedValues.y * (Math.PI / 180); + const radiansZ = updatedValues.z * (Math.PI / 180); + selectedWallItem.rotation.set(radiansX, radiansY, radiansZ); + + let RotatedWallItems: WallItem[] = []; + wallItems.forEach(async (item: Types.WallItem) => { + if (item.model?.parent?.uuid === selectedWallItem.uuid) { + + const quaternion = new THREE.Quaternion().setFromEuler( + new THREE.Euler(radiansX, radiansY, radiansZ) + ); + item.quaternion = [quaternion.x, quaternion.y, quaternion.z, quaternion.w]; + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // await setWallItem( + // organization, + // item.model?.uuid!, + // item.modelname!, + // item.type!, + // item.csgposition!, + // item.csgscale!, + // item.position!, + // [quaternion.x, quaternion.y, quaternion.z, quaternion.w], + // item.scale!, + // ) + + //SOCKET + + const data = { + organization: organization, + modeluuid: item.model?.uuid!, + modelname: item.modelname!, + type: item.type!, + csgposition: item.csgposition!, + csgscale: item.csgscale!, + position: item.position!, + quaternion: [quaternion.x, quaternion.y, quaternion.z, quaternion.w], + scale: item.scale!, + socketId: socket.id + } + + socket.emit('v1:wallItems:set', data); + } + RotatedWallItems.push(item as any); + }); + + const WallItemsForStorage = RotatedWallItems.map((item) => { + const { model, ...rest } = item; + return { + ...rest, + modeluuid: model?.uuid, + }; + }); + localStorage.setItem("WallItems", JSON.stringify(WallItemsForStorage)); + } + } else if (selectedFloorItem) { + if (header === "Position") { + setObjectPosition(updatedValues); + selectedFloorItem.position.set(updatedValues.x, updatedValues.y, updatedValues.z); + setFloorItems((prevItems: any) => { + if (!prevItems) { + return prevItems; // Return the previous state if it's null or undefined + } + let updatedItem: any = null; + const updatedItems = prevItems.map((item: any) => { + if (item.modeluuid === selectedFloorItem.uuid) { + updatedItem = { + ...item, + position: [selectedFloorItem.position.x, selectedFloorItem.position.y, selectedFloorItem.position.z] as [number, number, number], + } + return updatedItem; + } + return item; + }); + if (updatedItem && selectedFloorItem) { + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // setFloorItemApi( + // organization, + // updatedItem.modeluuid, + // updatedItem.modelname, + // [selectedFloorItem.position.x, selectedFloorItem.position.y, selectedFloorItem.position.z,], + // { "x": selectedFloorItem.rotation.x, "y": selectedFloorItem.rotation.y, "z": selectedFloorItem.rotation.z }, + // false, + // true, + // ); + + //SOCKET + + const data = { + organization: organization, + modeluuid: updatedItem.modeluuid, + modelname: updatedItem.modelname, + position: [selectedFloorItem.position.x, selectedFloorItem.position.y, selectedFloorItem.position.z], + rotation: { "x": selectedFloorItem.rotation.x, "y": selectedFloorItem.rotation.y, "z": selectedFloorItem.rotation.z }, + isLocked: false, + isVisible: true, + socketId: socket.id + } + + socket.emit('v1:FloorItems:set', data); + } + localStorage.setItem("floorItems", JSON.stringify(updatedItems)); + return updatedItems; + }); + } else if (header === "Scale") { + setObjectScale(updatedValues); + } else if (header === "Rotation") { + setObjectRotation(updatedValues); + const radiansX = updatedValues.x * (Math.PI / 180); + const radiansY = updatedValues.y * (Math.PI / 180); + const radiansZ = updatedValues.z * (Math.PI / 180); + selectedFloorItem.rotation.set(radiansX, radiansY, radiansZ); + setFloorItems((prevItems: any) => { + if (!prevItems) { + return prevItems; // Return the previous state if it's null or undefined + } + + let updatedItem: any = null; + const updatedItems = prevItems.map((item: any) => { + if (item.modeluuid === selectedFloorItem.uuid) { + updatedItem = { + ...item, + rotation: { _x: selectedFloorItem.rotation.x, _y: selectedFloorItem.rotation.y, _z: selectedFloorItem.rotation.z }, + } + return updatedItem; + } + return item; + }); + if (updatedItem && selectedFloorItem) { + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //REST + + // setFloorItemApi( + // organization, + // updatedItem.modeluuid, + // updatedItem.modelname, + // [selectedFloorItem.position.x, selectedFloorItem.position.y, selectedFloorItem.position.z,], + // { "x": selectedFloorItem.rotation.x, "y": selectedFloorItem.rotation.y, "z": selectedFloorItem.rotation.z }, + // false, + // true, + // ); + + //SOCKET + + const data = { + organization: organization, + modeluuid: updatedItem.modeluuid, + modelname: updatedItem.modelname, + position: [selectedFloorItem.position.x, selectedFloorItem.position.y, selectedFloorItem.position.z], + rotation: { "x": selectedFloorItem.rotation.x, "y": selectedFloorItem.rotation.y, "z": selectedFloorItem.rotation.z }, + isLocked: false, + isVisible: true, + socketId: socket.id + } + + socket.emit('v1:FloorItems:set', data); + } + localStorage.setItem("floorItems", JSON.stringify(updatedItems)); + return updatedItems; + }); + } + } + } + }, + [header, isLocked, selectedWallItem, wallItems] + ); + + const toggleLock = (axis: Axis) => { + setIsLocked((prevState) => ({ ...prevState, [axis]: !prevState[axis] })); + }; + + const getValues = () => { + switch (header) { + case "Position": + return objectPosition || new THREE.Vector3(0, 0, 0); + case "Scale": + return objectScale || new THREE.Vector3(1, 1, 1); + case "Rotation": + return objectRotation || new THREE.Euler(0, 0, 0, 'XYZ'); + default: + return {}; + } + }; + + return ( +
    +
    {header}
    + +
    + {axisConfigs.map(({ axis }) => ( +
    +
    {axis.toUpperCase()}
    +
    + handleInputChange(axis, e)} + disabled={isLocked[axis]} // Disable if locked + /> +
    +
    toggleLock(axis)}> + +
    +
    + ))} +
    +
    + ); +}; + +export default ObjectInputs; diff --git a/frontend/src/components/ui/inputs/regularDropDown.tsx b/frontend/src/components/ui/inputs/regularDropDown.tsx new file mode 100644 index 0000000..6ae8c7d --- /dev/null +++ b/frontend/src/components/ui/inputs/regularDropDown.tsx @@ -0,0 +1,77 @@ +import React, { useState, useEffect, useRef } from 'react'; +import { DropDownIcon } from '../../../assets/images/svgExports'; + +interface DropdownProps { + header: string; + options: string[]; + onSelect: (option: string) => void; // Callback for option selection +} + +const RegularDropDown: React.FC = ({ header, options, onSelect }) => { + const [isOpen, setIsOpen] = useState(false); + const [selectedOption, setSelectedOption] = useState(null); + + // Reference to the dropdown container + const dropdownRef = useRef(null); + + // Toggle dropdown visibility + const toggleDropdown = () => { + setIsOpen(prev => !prev); + }; + + // Handle option selection + const handleOptionClick = (option: string) => { + setSelectedOption(option); + onSelect(option); // Call the onSelect function passed from the parent + setIsOpen(false); // Close the dropdown after selection + }; + + // Handle clicks outside the dropdown + useEffect(() => { + const handleOuterClick = (event: MouseEvent) => { + if ( + dropdownRef.current && + !dropdownRef.current.contains(event.target as Node) + ) { + setIsOpen(false); // Close the dropdown if clicked outside + } + }; + + // Attach the event listener + document.addEventListener('mousedown', handleOuterClick); + + // Cleanup the event listener on component unmount + return () => { + document.removeEventListener('mousedown', handleOuterClick); + }; + }, []); + + return ( +
    + {/* Dropdown Header */} +
    +
    {selectedOption || header}
    +
    + +
    +
    + + {/* Dropdown Options */} + {isOpen && ( +
    + {options.map((option, index) => ( +
    handleOptionClick(option)} // Handle option click + > + {option} +
    + ))} +
    + )} +
    + ); +}; + +export default RegularDropDown; \ No newline at end of file diff --git a/frontend/src/components/ui/inputs/renaming.tsx b/frontend/src/components/ui/inputs/renaming.tsx new file mode 100644 index 0000000..55879d6 --- /dev/null +++ b/frontend/src/components/ui/inputs/renaming.tsx @@ -0,0 +1,102 @@ +import React, { + useEffect, + useState, + ChangeEvent, + KeyboardEvent, + useRef, +} from "react"; + +interface RenamingProps { + value: string; + changeValue: (newValue: string, index: number, details: string) => void; + index: number; + details: string; + editable: boolean; +} + +const Renaming: React.FC = ({ + value, + changeValue, + index, + details, + editable, +}) => { + const [isEditing, setEditing] = useState(false); + const [text, setText] = useState(value); + const inputRef = useRef(null); + + // Update text when the value prop changes + useEffect(() => { + setText(value); + }, [value]); + + const handleBlur = () => { + setEditing(false); + // Only change value if it has been modified + if (text.trim() !== value) { + changeValue(text, index, details); + } + }; + // Handle clicks outside the input to trigger blur + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if ( + inputRef.current && + !inputRef.current.contains(event.target as Node) + ) { + handleBlur(); + } + }; + + document.addEventListener("mousedown", handleClickOutside); + return () => { + document.removeEventListener("mousedown", handleClickOutside); + }; + }, []); + + const handleInputChange = (e: ChangeEvent) => { + setText(e.target.value); + }; + //double click + const handleDoubleClick = () => { + //make the text to be editable + if (editable) { + setEditing(true); + } + }; + + const handleUpdate = (e: KeyboardEvent) => { + //make the inputbox into uneditable + if (e.key === "Enter") { + handleBlur(); + } else if (e.key === "Escape") { + setEditing(false); + setText(value); // Reset text to original value + } + }; + + return ( + <> + {isEditing ? ( + + ) : ( +

    + {text} + {/* the edited value */} +

    + )} + + ); +}; + +export default Renaming; diff --git a/frontend/src/components/ui/inputs/searchComponent.tsx b/frontend/src/components/ui/inputs/searchComponent.tsx new file mode 100644 index 0000000..1272400 --- /dev/null +++ b/frontend/src/components/ui/inputs/searchComponent.tsx @@ -0,0 +1,39 @@ +import React from "react"; + +// Ensure you import FilteredAssets if defined in another file +interface FilteredAssets { + name: string; + img?: string; // Optional for the first asset type + svg?: JSX.Element; // Optional for the second asset type +} + +interface FilteredProps { + assets: FilteredAssets[]; + inputData: string; + setFilteredData: React.Dispatch>; +} + +const SearchComponent: React.FC = ({ + assets, + inputData, + setFilteredData, +}) => { + React.useEffect(() => { + // Filter assets based on inputData + if (inputData.trim()) { + const filteredAssets = assets.filter((asset) => + asset.name + .toLowerCase() + .replace(/\s+/g, "") + .includes(inputData.toLowerCase().replace(/\s+/g, "")) + ); + setFilteredData(filteredAssets); + } else { + setFilteredData(assets); + } + }, [inputData, assets, setFilteredData]); + + return null; // No rendering needed +}; + +export default SearchComponent; diff --git a/frontend/src/components/ui/inputs/toggleSwitch.tsx b/frontend/src/components/ui/inputs/toggleSwitch.tsx new file mode 100644 index 0000000..88b2ad7 --- /dev/null +++ b/frontend/src/components/ui/inputs/toggleSwitch.tsx @@ -0,0 +1,69 @@ +import React, { useState } from "react"; + +import { + useToggleView, + useDeletePointOrLine, + useMovePoint, + useDeleteModels, + useSelectedWallItem, + useRoofVisibility, + useWallVisibility, + useResetCamera, + useAddAction, +} from "../../../store/store"; + +interface ToggleSwitchProps { + labels: string[]; + initialState?: boolean; + onToggle?: (newState: boolean) => void; +} + +const ToggleSwitch: React.FC = ({ + labels, + initialState = true, +}) => { + + const { toggleView, setToggleView } = useToggleView(); + const { deleteModels, setDeleteModels } = useDeleteModels(); + const { addAction, setAddAction } = useAddAction(); + const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem(); + const [isAM, setIsAM] = useState(initialState); + + const toggleSwitch = () => { + if (isAM) { + setSelectedWallItem(null); + setDeleteModels(false); + setAddAction(null); + setToggleView(true); + } + else { + setToggleView(false); + } + setIsAM(!isAM); + }; + + return ( +
    +
    + + {labels[0]} + + + {labels[1]} + +
    +
    +
    + ); +}; + +export default ToggleSwitch; diff --git a/frontend/src/components/ui/note.txt b/frontend/src/components/ui/note.txt new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/components/ui/sideBar/assetLibrary.tsx b/frontend/src/components/ui/sideBar/assetLibrary.tsx new file mode 100644 index 0000000..8052863 --- /dev/null +++ b/frontend/src/components/ui/sideBar/assetLibrary.tsx @@ -0,0 +1,80 @@ +import React, { useState, useEffect, useRef, useCallback } from "react"; +import { useSelectedItem } from "../../../store/store"; +import { getAssetImages } from "../../../services/factoryBuilder/assest/assets/getAssetImages"; + +interface FilteredAssets { + filename: string; + thumbnail: string; + modelfileID: string; +} + +const AssetLibrary: React.FC = () => { + const { setSelectedItem } = useSelectedItem(); + const [assets, setAssets] = useState([]); + const [cursor, setCursor] = useState(undefined); + const [loading, setLoading] = useState(false); + const [hasNextPage, setHasNextPage] = useState(true); + + const observer = useRef(null); + const lastAssetRef = useCallback( + (node: HTMLDivElement | null) => { + if (loading || !hasNextPage) return; + + if (observer.current) observer.current.disconnect(); + + observer.current = new IntersectionObserver((entries) => { + if (entries[0].isIntersecting) { + fetchMoreAssets(); + } + }); + + if (node) observer.current.observe(node); + }, + [loading, hasNextPage] + ); + + // Fetch assets function + const fetchMoreAssets = async () => { + if (!hasNextPage) return; + + setLoading(true); + try { + const res = await getAssetImages(cursor); + setAssets((prevAssets) => [...prevAssets, ...res.items]); + setCursor(res.nextCursor || undefined); + setHasNextPage(res.hasNextPage); + } catch (error) { + console.error("Error fetching assets:", error); + } finally { + setLoading(false); + } + }; + + // Fetch initial assets on mount + useEffect(() => { + fetchMoreAssets(); + }, []); + + return ( +
    + {assets.map((asset, index) => ( +
    + {asset.filename} setSelectedItem({ name: asset.filename, id: asset.modelfileID })} + /> +
    {asset.filename}
    +
    + ))} + {loading &&
    Loading more assets...
    } +
    + ); +}; + +export default AssetLibrary; diff --git a/frontend/src/components/ui/sideBar/assets.tsx b/frontend/src/components/ui/sideBar/assets.tsx new file mode 100644 index 0000000..8764f40 --- /dev/null +++ b/frontend/src/components/ui/sideBar/assets.tsx @@ -0,0 +1,73 @@ +import { useState } from "react"; +import asset1 from "../../../assets/images/tempimages/asset1.png"; +import asset2 from "../../../assets/images/tempimages/asset2.png"; +import asset3 from "../../../assets/images/tempimages/asset3.png"; +import asset4 from "../../../assets/images/tempimages/asset4.png"; +import asset5 from "../../../assets/images/tempimages/asset5.png"; +import asset6 from "../../../assets/images/tempimages/asset6.png"; +import asset7 from "../../../assets/images/tempimages/asset7.png"; +import asset8 from "../../../assets/images/tempimages/asset8.png"; +import asset9 from "../../../assets/images/tempimages/asset9.png"; +import { FilterIcon, SearchIcon } from "../../../assets/images/svgExports"; +import SearchComponent from "../inputs/searchComponent"; +interface FilteredAssets { + name: string; // The name of the asset + img?: string; // An optional property for image URLs (used in the AssetsLists component) + svg?: JSX.Element; // An optional property for SVG elements (used in the Footer component) +} + +const AssetsLists = () => { + const [inputData, setInputData] = useState(""); + const [filteredData, setFilteredData] = useState([]); // Ensure this matches + + const assets: FilteredAssets[] = [ + { name: "Asset 1", img: asset1 }, + { name: "Asset 2", img: asset2 }, + { name: "Asset 3", img: asset3 }, + { name: "Asset 4", img: asset4 }, + { name: "Asset 5", img: asset5 }, + { name: "Asset 6", img: asset6 }, + { name: "Asset 7", img: asset7 }, + { name: "Asset 8", img: asset8 }, + { name: "Asset 9", img: asset9 }, + ]; + + const handleInputChange = (event: React.ChangeEvent) => { + setInputData(event.target.value); + }; + + return ( +
    +
    +
    + +
    +
    + handleInputChange(e)} + /> +
    + +
    +
    +
    + +
    + {filteredData.map((asset, index) => ( +
    + {asset.name} +
    {asset.name}
    +
    + ))} +
    +
    + ); +}; + +export default AssetsLists; diff --git a/frontend/src/components/ui/sideBar/factory builder/material.tsx b/frontend/src/components/ui/sideBar/factory builder/material.tsx new file mode 100644 index 0000000..109c490 --- /dev/null +++ b/frontend/src/components/ui/sideBar/factory builder/material.tsx @@ -0,0 +1,192 @@ +import React, { useState } from "react"; +import FrameRangeInput from "../frameRangeInput"; // Importing a custom range input component + +const Material = () => { + // State variables for material properties + const [baseColor, setBaseColor] = useState(null); + const [metallic, setMetallic] = useState(null); + const [roughness, setRoughness] = useState(0.5); + const [specular, setSpecular] = useState(0.3); + const [transmission, setTransmission] = useState(0.3); + const [alpha, setAlpha] = useState(0.8); + const [emission, setEmission] = useState(0.8); + const [ior, setIor] = useState(0.8); + const [normal, setNormal] = useState(null); + + // Handlers for file input changes + const handleBaseColorChange = ( + event: React.ChangeEvent + ) => { + if (event.target.files) { + setBaseColor(event.target.files[0]); // Set base color file + } + }; + + const handleMetallicChange = (event: React.ChangeEvent) => { + if (event.target.files) { + setMetallic(event.target.files[0]); // Set metallic texture file + } + }; + + // Handlers for range input changes + const handleRoughnessChange = ( + event: React.ChangeEvent + ) => { + setRoughness(Number(event.target.value)); // Update roughness value + }; + + const handleSpecularChange = (event: React.ChangeEvent) => { + setSpecular(Number(event.target.value)); // Update specular value + }; + + const handleTransmissionChange = ( + event: React.ChangeEvent + ) => { + setTransmission(Number(event.target.value)); // Update transmission value + }; + + const handleAlphaChange = (event: React.ChangeEvent) => { + setAlpha(Number(event.target.value)); // Update alpha value + }; + + const handleEmissionChange = (event: React.ChangeEvent) => { + setEmission(Number(event.target.value)); // Update emission value + }; + + const handleIorChange = (event: React.ChangeEvent) => { + setIor(Number(event.target.value)); // Update index of refraction (IOR) value + }; + + const handleNormalChange = (event: React.ChangeEvent) => { + if (event.target.files) { + setNormal(event.target.files[0]); // Set normal map file + } + }; + + // Function to increment the value while ensuring it doesn't exceed 1 + const incrementValue = ( + setValue: React.Dispatch> + ) => { + setValue((prev) => Math.min(prev + 0.1, 1)); + }; + + // Function to decrement the value while ensuring it doesn't go below 0 + const decrementValue = ( + setValue: React.Dispatch> + ) => { + setValue((prev) => Math.max(prev - 0.1, 0)); + }; + + return ( +
    +
    Material name
    +
    +
    +
    + + +
    +
    + + {/* File input for metallic texture can be added here */} +
    +
    + +
    + + {roughness.toFixed(2)} {/* Display roughness value */} +
    +
    +
    + +
    + + {specular.toFixed(2)} {/* Display specular value */} +
    +
    +
    + +
    + + {transmission.toFixed(2)}{" "} + {/* Display transmission value */} +
    +
    +
    + +
    + + {alpha.toFixed(2)} {/* Display alpha value */} +
    +
    +
    + +
    + + {emission.toFixed(2)} {/* Display emission value */} +
    +
    +
    + {/* Custom range input for IOR */} + incrementValue(setIor)} // Increment IOR value + onDecrement={() => decrementValue(setIor)} // Decrement IOR value + onChange={setIor} // Pass the setter directly + /> +
    +
    + + {/* File input for normal map can be added here */} +
    +
    +
    + ); +}; + +export default Material; diff --git a/frontend/src/components/ui/sideBar/factory builder/object.tsx b/frontend/src/components/ui/sideBar/factory builder/object.tsx new file mode 100644 index 0000000..6eb77f0 --- /dev/null +++ b/frontend/src/components/ui/sideBar/factory builder/object.tsx @@ -0,0 +1,261 @@ +import ObjectInputs from "../../inputs/objectInputs"; +import { CloseIcon, FilterIcon } from "../../../../assets/images/svgExports"; +import { useState } from "react"; + +interface UserData { + dataName: string; + value: string; +} + +const Object = () => { + const [userDatas, setUserDatas] = useState([ + { dataName: "Table 01", value: "" }, + ]); + + const [editData, setEditData] = useState({ + type: "", + propertyName: "", + defaultValue: "", + min: "", + max: "", + step: "", + precision: "", + subType: "", + description: "", + }); + + const handleAddUserData = () => { + setUserDatas((prevDatas) => [ + ...prevDatas, + { dataName: `Table 0${prevDatas.length + 1}`, value: "" }, + ]); + }; + + const handleDeleteUserData = (index: number) => { + if (userDatas.length > 1) { + setUserDatas((prevDatas) => { + const newData = prevDatas.filter((_, i) => i !== index); + return newData.map((data, idx) => ({ + ...data, + dataName: `Table 0${idx + 1}`, + })); + }); + } + }; + + const handleValueChange = (index: number, newValue: string) => { + setUserDatas((prevDatas) => { + const newData = [...prevDatas]; + newData[index].value = newValue; + return newData; + }); + }; + + const handleEditDataChange = ( + e: React.ChangeEvent + ) => { + const { name, value } = e.target; + setEditData((prevData) => ({ + ...prevData, + [name]: value, + })); + }; + + const handleAddEditData = () => { + // Reset editData if needed + setEditData({ + type: "", + propertyName: "", + defaultValue: "", + min: "", + max: "", + step: "", + precision: "", + subType: "", + description: "", + }); + + console.log("editData: ", editData); + }; + + return ( +
    +
    +
    Table - 01
    +
    Mesh
    +
    + +
    + + + +
    + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    User data
    +
    + + Add +
    +
    + +
    + {userDatas.map((data, index) => ( +
    +
    {data.dataName}
    +
    + + handleValueChange(index, String(e.target.value)) + } + /> +
    + +
    +
    handleDeleteUserData(index)} + > + +
    +
    +
    + ))} +
    +
    + +
    +
    +
    Edit data
    +
    + +
    +
    +
    +
    Type
    + +
    + +
    +
    Property name
    + +
    + +
    +
    Default value
    + +
    + +
    +
    +
    Min
    + +
    + +
    +
    Max
    + +
    +
    + +
    +
    Step
    + +
    + +
    +
    Precision
    + +
    + +
    +
    Sub type
    + +
    + +
    +
    Description
    + +
    +
    +
    + + +
    +
    +
    +
    + ); +}; + +export default Object; diff --git a/frontend/src/components/ui/sideBar/frameRangeInput.tsx b/frontend/src/components/ui/sideBar/frameRangeInput.tsx new file mode 100644 index 0000000..76ca26c --- /dev/null +++ b/frontend/src/components/ui/sideBar/frameRangeInput.tsx @@ -0,0 +1,43 @@ +import React from "react"; +import { FillDropDown, FillDropUp } from "../../../assets/images/svgExports"; + +interface FrameRangeInputProps { + label: string; + value: number; + onIncrement: () => void; + onDecrement: () => void; + onChange: (newValue: number) => void; // New prop for input change +} + +const FrameRangeInput: React.FC = ({ + label, + value, + onIncrement, + onDecrement, + onChange, // Destructure new prop +}) => { + const handleInputChange = (event: React.ChangeEvent) => { + const newValue = parseInt(event.target.value, 10); + if (!isNaN(newValue)) { + onChange(newValue); // Call onChange with the new value + } + }; + + return ( +
    + {label &&
    {label}
    } +
    +
    + +
    + {" "} + {/* Add onChange handler */} +
    + +
    +
    +
    + ); +}; + +export default FrameRangeInput; diff --git a/frontend/src/components/ui/sideBar/global/worldSettings.tsx b/frontend/src/components/ui/sideBar/global/worldSettings.tsx new file mode 100644 index 0000000..5424a98 --- /dev/null +++ b/frontend/src/components/ui/sideBar/global/worldSettings.tsx @@ -0,0 +1,262 @@ +import { useEffect, useState } from "react"; +import { useWallVisibility, useRoofVisibility, useElevation, useAzimuth, useResetCamera, useToggleView, useSelectedWallItem, useRenderDistance, useShadows } from "../../../../store/store"; + +import { useSocketStore } from "../../../../store/store"; +import { findEnvironment } from "../../../../services/factoryBuilder/environment/findEnvironment"; +import { setEnvironment } from "../../../../services/factoryBuilder/environment/setEnvironment"; + +function WorldSettings() { + const { toggleView, setToggleView } = useToggleView(); + const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem(); + const { roofVisibility, setRoofVisibility } = useRoofVisibility(); + const { wallVisibility, setWallVisibility } = useWallVisibility(); + const { shadows, setShadows } = useShadows(); + const { resetCamera, setResetCamera } = useResetCamera(); + const { elevation, setElevation } = useElevation(); + const { azimuth, setAzimuth } = useAzimuth(); + const { renderDistance, setRenderDistance } = useRenderDistance(); + const { socket } = useSocketStore(); + + // Load roof and wall visibility from backend on component mount + + // useEffect(() => { + // localStorage.setItem("Visibility", JSON.stringify({ "roofVisibility": roofVisibility, "wallVisibility": wallVisibility })); + // }, [roofVisibility, wallVisibility]); + + // Function to toggle roof visibility + const changeRoofVisibility = async () => { + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //using REST + const data = await setEnvironment(organization, localStorage.getItem('userId')!, wallVisibility, !roofVisibility, shadows); + // console.log('data: ', data); + + //using Socket + // const visData = { + // organization: organization, + // userId: localStorage.getItem('userId')!, + // wallVisibility: wallVisibility, + // roofVisibility: !roofVisibility, + // shadowVisibility: shadows, + // socketId: socket.id + // }; + // socket.emit('v1:Environment:set', visData) + + setRoofVisibility(!roofVisibility); // Toggle roof visibility + }; + + // Function to toggle wall visibility + const changeWallVisibility = async () => { + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //using REST + const data = await setEnvironment(organization, localStorage.getItem('userId')!, !wallVisibility, roofVisibility, shadows); + // console.log('data: ', data); + + //using Socket + // const visData = { + // organization: organization, + // userId: localStorage.getItem('userId')!, + // wallVisibility: !wallVisibility, + // roofVisibility: roofVisibility, + // shadowVisibility: shadows, + // socketId: socket.id + // }; + // socket.emit('v1:Environment:set', visData) + + setWallVisibility(!wallVisibility); // Toggle wall visibility + }; + + const shadowVisibility = async () => { + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + //using REST + const data = await setEnvironment(organization, localStorage.getItem('userId')!, wallVisibility, roofVisibility, !shadows); + // console.log('data: ', data); + + //using Socket + // const visData = { + // organization: organization, + // userId: localStorage.getItem('userId')!, + // wallVisibility: wallVisibility, + // roofVisibility: roofVisibility, + // shadowVisibility: !shadows, + // socketId: socket.id + // }; + // socket.emit('v1:Environment:set', visData) + + setShadows(!shadows); + } + + // Function to reset camera + const toggleResetCamera = () => { + if (!toggleView) { + setResetCamera(true); // Trigger reset camera action + } + }; + + // Function to clear local storage + const clearStorage = () => { + setSelectedWallItem(null); // Clear selected wall item + localStorage.setItem("Lines", JSON.stringify([])); // Clear lines + localStorage.setItem("WallItems", JSON.stringify([])); // Clear wall items + localStorage.setItem("FloorItems", JSON.stringify([])); // Clear floor items + }; + + function changeElevation(e: React.ChangeEvent) { + const value = parseInt(e.target.value, 10); + if (value < 2) { + setElevation(2); + } else if (value > 90) { + setElevation(90); + } else { + setElevation(value); + } + } + + function changeAzimuth(e: React.ChangeEvent) { + const value = parseInt(e.target.value, 10); + if (value < -180) { + setAzimuth(-180); + } else if (value > 180) { + setAzimuth(180); + } else { + setAzimuth(value); + } + } + function changeRenderDistance(e: any) { + if (parseInt(e.target.value) < 20) { + setRenderDistance(20); + } else if (parseInt(e.target.value) > 75) { + setRenderDistance(75); + } else { + setRenderDistance(parseInt(e.target.value)); + } + } + + return ( +
    +
    +
    Environment
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    + + +
    + +
    +
    + +
    + + +
    + +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    + +
    +
    +
    +
    +
    +
    + ); +}; + +export default WorldSettings; diff --git a/frontend/src/components/ui/sideBar/object.tsx b/frontend/src/components/ui/sideBar/object.tsx new file mode 100644 index 0000000..b8bd4c4 --- /dev/null +++ b/frontend/src/components/ui/sideBar/object.tsx @@ -0,0 +1,109 @@ +import ObjectInputs from "../inputs/objectInputs"; +import { CloseIcon, FilterIcon } from "../../../assets/images/svgExports"; + +const Object = () => { + return ( +
    +
    +
    Table - 01
    +
    Mesh
    +
    + +
    + + + +
    + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    User data
    +
    + Add
    +
    + +
    + {/* below section is a mapped content */} +
    +
    Table 01
    +
    + + +
    X
    +
    +
    +
    +
    + +
    +
    +
    Edit data
    +
    + +
    +
    +
    Type
    + +
    +
    +
    Property name
    + +
    +
    +
    Default value
    + +
    +
    +
    +
    Min
    + +
    +
    +
    Max
    + +
    +
    +
    +
    Step
    + +
    +
    +
    Precision
    + +
    +
    +
    Sub type
    + +
    +
    +
    Description
    + {/* */} + +
    +
    + + +
    +
    +
    +
    + ); +}; + +export default Object; diff --git a/frontend/src/components/ui/sideBar/outline.tsx b/frontend/src/components/ui/sideBar/outline.tsx new file mode 100644 index 0000000..f896d4c --- /dev/null +++ b/frontend/src/components/ui/sideBar/outline.tsx @@ -0,0 +1,9 @@ +import React from 'react' + +const Outline = () => { + return ( +
    Outline
    + ) +} + +export default Outline diff --git a/frontend/src/components/ui/sideBar/process creator/advanced.tsx b/frontend/src/components/ui/sideBar/process creator/advanced.tsx new file mode 100644 index 0000000..65095ab --- /dev/null +++ b/frontend/src/components/ui/sideBar/process creator/advanced.tsx @@ -0,0 +1,212 @@ +import React, { useState } from "react"; +import AdvancedPropertiesProperties from "./advancedPropertiesProperties"; +import AdvancedGlobalProperties from "./advancedGlobalProperties"; + +const Advanced = () => { + const [baseColor, setBaseColor] = useState(null); + const [metallic, setMetallic] = useState(null); + const [roughness, setRoughness] = useState(0.5); + const [specular, setSpecular] = useState(0.3); + const [transmission, setTransmission] = useState(0.3); + const [alpha, setAlpha] = useState(0.8); + const [emission, setEmission] = useState(0.8); + const [ior, setIor] = useState(0.8); + const [normal, setNormal] = useState(null); + + const handleBaseColorChange = ( + event: React.ChangeEvent + ) => { + if (event.target.files) { + setBaseColor(event.target.files[0]); + } + }; + + const handleMetallicChange = (event: React.ChangeEvent) => { + if (event.target.files) { + setMetallic(event.target.files[0]); + } + }; + + const handleRoughnessChange = ( + event: React.ChangeEvent + ) => { + setRoughness(Number(event.target.value)); + }; + + const handleSpecularChange = (event: React.ChangeEvent) => { + setSpecular(Number(event.target.value)); + }; + + const handleTransmissionChange = ( + event: React.ChangeEvent + ) => { + setTransmission(Number(event.target.value)); + }; + + const handleAlphaChange = (event: React.ChangeEvent) => { + setAlpha(Number(event.target.value)); + }; + + const handleEmissionChange = (event: React.ChangeEvent) => { + setEmission(Number(event.target.value)); + }; + + const handleIorChange = (event: React.ChangeEvent) => { + setIor(Number(event.target.value)); + }; + + const handleNormalChange = (event: React.ChangeEvent) => { + if (event.target.files) { + setNormal(event.target.files[0]); + } + }; + + let [active, setActive] = useState("advancedProperties"); + + return ( + //
    + //
    Material name
    + //
    + //
    + //
    + // + //
    + // + //
    + //
    + //
    + // + // {/* */} + //
    + //
    + // + //
    + // + // {roughness.toFixed(2)} + //
    + //
    + //
    + // + //
    + // + // {specular.toFixed(2)} + //
    + //
    + //
    + // + //
    + // + // {transmission.toFixed(2)} + //
    + //
    + //
    + // + //
    + // + // {alpha.toFixed(2)} + //
    + //
    + //
    + // + //
    + // + // {emission.toFixed(2)} + //
    + //
    + //
    + // + //
    + // + // {ior.toFixed(2)} + //
    + //
    + //
    + // + //
    + //
    + //
    + +
    +
    +
    setActive("advancedProperties")} + > + Advanced properties +
    +
    setActive("global")} + > + Global +
    +
    + + {active === "advancedProperties" ? ( + + ) : ( + + )} +
    + ); +}; + +export default Advanced; diff --git a/frontend/src/components/ui/sideBar/process creator/advancedGlobalProperties.tsx b/frontend/src/components/ui/sideBar/process creator/advancedGlobalProperties.tsx new file mode 100644 index 0000000..1eb7e3d --- /dev/null +++ b/frontend/src/components/ui/sideBar/process creator/advancedGlobalProperties.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +const AdvancedGlobalProperties = () => { + return ( +
    + +
    + ) +} + +export default AdvancedGlobalProperties diff --git a/frontend/src/components/ui/sideBar/process creator/advancedPropertiesProperties.tsx b/frontend/src/components/ui/sideBar/process creator/advancedPropertiesProperties.tsx new file mode 100644 index 0000000..442e2a5 --- /dev/null +++ b/frontend/src/components/ui/sideBar/process creator/advancedPropertiesProperties.tsx @@ -0,0 +1,33 @@ +import React, { useState } from "react"; +import ObjectInputs from "../../inputs/objectInputs"; +import { DropDownIcon } from "../../../../assets/images/svgExports"; + +const AdvancedPropertiesProperties = () => { + // Define state to manage the visibility of the transform section + const [isTransformOpen, setTransformOpen] = useState(true); + + return ( +
    +
    +
    setTransformOpen(!isTransformOpen)} + > +

    Transform

    +
    + +
    +
    + {isTransformOpen && ( +
    + + + +
    + )} +
    +
    + ); +}; + +export default AdvancedPropertiesProperties; diff --git a/frontend/src/components/ui/sideBar/process creator/basic.tsx b/frontend/src/components/ui/sideBar/process creator/basic.tsx new file mode 100644 index 0000000..104d1c8 --- /dev/null +++ b/frontend/src/components/ui/sideBar/process creator/basic.tsx @@ -0,0 +1,104 @@ +import React, { useState } from "react"; +import ObjectInputs from "../../inputs/objectInputs"; +import BasicProperties from "./basicProperties"; // Import the new component +import { CloseIcon, FilterIcon } from "../../../../assets/images/svgExports"; +import GlobalProperties from "./globalProperties"; + +interface UserData { + dataName: string; + value: string; +} + +const Basic: React.FC = () => { + const [userDatas, setUserDatas] = useState([ + { dataName: "Table 01", value: "" }, + ]); + + const handleAddUserData = () => { + setUserDatas((prevDatas) => [ + ...prevDatas, + { dataName: `Table 0${prevDatas.length + 1}`, value: "" }, + ]); + }; + + const handleDeleteUserData = (index: number) => { + if (userDatas.length > 1) { + setUserDatas((prevDatas) => { + const newData = prevDatas.filter((_, i) => i !== index); + return newData.map((data, idx) => ({ + ...data, + dataName: `Table 0${idx + 1}`, + })); + }); + } + }; + + const handleValueChange = (index: number, newValue: string) => { + setUserDatas((prevDatas) => { + const newData = [...prevDatas]; + newData[index].value = newValue; + return newData; + }); + }; + + let [active, setActive] = useState("basicProperties"); + + return ( +
    + {/*
    +
    setActive("basicProperties")} + > + Basic properties +
    +
    setActive("global")} + > + Global +
    +
    */} + + {active === "basicProperties" ? ( + + ) : ( + + )} + + {/*
    +
    +
    User data
    +
    + + Add +
    +
    + +
    + {userDatas.map((data, index) => ( +
    +
    {data.dataName}
    +
    + + handleValueChange(index, String(e.target.value)) + } + /> + +
    handleDeleteUserData(index)} + > +
    +
    +
    + ))} +
    +
    */} +
    + ); +}; + +export default Basic; diff --git a/frontend/src/components/ui/sideBar/process creator/basicProperties.tsx b/frontend/src/components/ui/sideBar/process creator/basicProperties.tsx new file mode 100644 index 0000000..8be2bab --- /dev/null +++ b/frontend/src/components/ui/sideBar/process creator/basicProperties.tsx @@ -0,0 +1,164 @@ +import React, { useState } from "react"; +import { + DropDownIcon, + FillDropDown, + FillDropUp, +} from "../../../../assets/images/svgExports"; +import ObjectInputs from "../../inputs/objectInputs"; +import RegularDropDown from "../../inputs/regularDropDown"; +import FrameRangeInput from "../frameRangeInput"; // Adjust the path as needed + +const BasicProperties: React.FC = () => { + const [duration, setDuration] = useState(10); + const [delay, setDelay] = useState(10); + const [startFrame, setStartFrame] = useState(10); + const [endFrame, setEndFrame] = useState(10); + const [stepFrame, setStepFrame] = useState(10); + const [frameRate, setFrameRate] = useState(10); + const [keys, setKeys] = useState(["Base", "Key 2"]); + const [selectedKey, setSelectedKey] = useState("Base"); + const [selectedEasing, setSelectedEasing] = useState(null); + + // State management for sections + const [isStateManagementOpen, setStateManagementOpen] = useState(true); + const [isTimeManagementOpen, setTimeManagementOpen] = useState(true); + const [isEasingOpen, setEasingOpen] = useState(true); + const [isTransformOpen, setTransformOpen] = useState(true); + + const incrementValue = ( + setter: React.Dispatch> + ) => { + setter((prev) => prev + 1); + }; + + const decrementValue = ( + setter: React.Dispatch> + ) => { + setter((prev) => (prev > 0 ? prev - 1 : 0)); + }; + + const addKey = () => { + const newKey = `Key ${keys.length + 1}`; + setKeys((prevKeys) => [...prevKeys, newKey]); + }; + + const handleKeyClick = (key: string) => { + setSelectedKey(key); + }; + + // Array for frame range inputs + const frameControls = [ + { label: "Duration", value: startFrame, setValue: setStartFrame }, + { label: "Delay", value: endFrame, setValue: setEndFrame }, + ]; + + return ( +
    + {/* State Management Section */} +
    +
    setStateManagementOpen(!isStateManagementOpen)} + > +

    State Management

    +
    + +
    +
    + {isStateManagementOpen && ( +
    +
    +
    Keys
    +
    + + Add +
    +
    +
    + {keys.map((key, index) => ( +
    handleKeyClick(key)} + > +
    {key}
    +
    + ))} +
    +
    + )} +
    + + {/* Time Management Section */} +
    +
    setTimeManagementOpen(!isTimeManagementOpen)} + > +

    Time Management

    +
    + +
    +
    + {isTimeManagementOpen && ( +
    + {frameControls.map(({ label, value, setValue }) => ( + incrementValue(setValue)} + onDecrement={() => decrementValue(setValue)} + onChange={setValue} // Pass the setter directly + /> + ))} +
    + )} +
    + + {/* Easing Section */} +
    +
    setEasingOpen(!isEasingOpen)} + > + Easing +
    + +
    +
    + {isEasingOpen && ( +
    +
    Interpolation
    + +
    + )} +
    + + {/* Transform Section */} +
    +
    setTransformOpen(!isTransformOpen)} + > +

    Transform

    +
    + +
    +
    + {isTransformOpen && ( +
    + + + +
    + )} +
    +
    + ); +}; + +export default BasicProperties; diff --git a/frontend/src/components/ui/sideBar/process creator/globalProperties.tsx b/frontend/src/components/ui/sideBar/process creator/globalProperties.tsx new file mode 100644 index 0000000..e76bf76 --- /dev/null +++ b/frontend/src/components/ui/sideBar/process creator/globalProperties.tsx @@ -0,0 +1,262 @@ +import React, { useState } from "react"; +import FrameRangeInput from "../frameRangeInput"; // Adjust the import path as necessary +import { DropDownIcon } from "../../../../assets/images/svgExports"; // Ensure DropDownIcon is correctly imported +import RegularDropDown from "../../inputs/regularDropDown"; // Import the RegularDropDown component + +const GlobalProperties: React.FC = () => { + // States for Frame Range section + const [startFrame, setStartFrame] = useState(10); + const [endFrame, setEndFrame] = useState(10); + const [stepFrame, setStepFrame] = useState(10); + const [frameRate, setFrameRate] = useState(10); + + // States for Format section + const [resolutionX, setResolutionX] = useState(34); + const [resolutionY, setResolutionY] = useState(34); + const [resolutionPercent, setResolutionPercent] = useState(5); + const [aspectX, setAspectX] = useState(34); + const [aspectY, setAspectY] = useState(34); + + // Sample count, View, Look, Format, and Color for dropdown + const [sampleCount, setSampleCount] = useState("24"); + const [view, setView] = useState(""); + const [look, setLook] = useState(""); + const [format, setFormat] = useState(""); + const [color, setColor] = useState(""); + + // Dropdown visibility toggles + const [isFrameDropdownOpen, setFrameDropdownOpen] = useState(true); + const [isFormatDropdownOpen, setFormatDropdownOpen] = useState(true); + const [isColorDropdownOpen, setColorDropdownOpen] = useState(true); + const [isFileDropdownOpen, setFileDropdownOpen] = useState(true); + const [isRenderDropdownOpen, setRenderDropdownOpen] = useState(true); // New state for Render Framework + + const incrementValue = ( + setter: React.Dispatch> + ) => { + setter((prev) => prev + 1); + }; + + const decrementValue = ( + setter: React.Dispatch> + ) => { + setter((prev) => (prev > 0 ? prev - 1 : 0)); + }; + + const frameControls = [ + { label: "Start", value: startFrame, setValue: setStartFrame }, + { label: "End", value: endFrame, setValue: setEndFrame }, + { label: "Step", value: stepFrame, setValue: setStepFrame }, + { label: "Frame Rate", value: frameRate, setValue: setFrameRate }, + ]; + + const resolutionControls = [ + { label: "X", value: resolutionX, setValue: setResolutionX }, + { label: "Y", value: resolutionY, setValue: setResolutionY }, + { label: "%", value: resolutionPercent, setValue: setResolutionPercent }, + ]; + + const aspectControls = [ + { label: "X", value: aspectX, setValue: setAspectX }, + { label: "Y", value: aspectY, setValue: setAspectY }, + ]; + + const handleDropdownSelect = + (setter: React.Dispatch>) => + (option: string) => { + setter(option); + }; + + return ( +
    + {/* Frame Range Section */} +
    +
    setFrameDropdownOpen((prev) => !prev)} + > + Frame range +
    + +
    +
    + {isFrameDropdownOpen && ( +
    + {frameControls.map(({ label, value, setValue }) => ( +
    + incrementValue(setValue)} + onDecrement={() => decrementValue(setValue)} + onChange={setValue} + /> +
    + ))} +
    + )} +
    + + {/* Format Section */} +
    +
    setFormatDropdownOpen((prev) => !prev)} + > + Format +
    + +
    +
    + {isFormatDropdownOpen && ( + <> +
    +
    +
    Resolution
    +
    + {resolutionControls.map(({ label, value, setValue }) => ( +
    + incrementValue(setValue)} + onDecrement={() => decrementValue(setValue)} + onChange={setValue} + /> +
    + ))} +
    +
    +
    +
    +
    +
    Aspect
    +
    + {aspectControls.map(({ label, value, setValue }) => ( +
    + incrementValue(setValue)} + onDecrement={() => decrementValue(setValue)} + onChange={setValue} + /> +
    + ))} +
    +
    +
    + {/* Frame Rate control */} +
    +
    +
    Frame Rate
    +
    + incrementValue(setFrameRate)} + onDecrement={() => decrementValue(setFrameRate)} + onChange={setFrameRate} + /> +
    +
    +
    + + )} +
    + + {/* Render Framework Section */} +
    +
    setRenderDropdownOpen((prev) => !prev)} + > + Render framework +
    + +
    +
    + {isRenderDropdownOpen && ( +
    +
    +
    Sample count
    + +
    +
    + )} +
    + + {/* Color Management Section */} +
    +
    setColorDropdownOpen((prev) => !prev)} + > + Color management +
    + +
    +
    + {isColorDropdownOpen && ( +
    +
    +
    View
    + +
    +
    +
    Look
    + +
    +
    + )} +
    + + {/* File Format Section */} +
    +
    setFileDropdownOpen((prev) => !prev)} + > + File format +
    + +
    +
    + {isFileDropdownOpen && ( +
    +
    +
    Format
    + +
    +
    +
    Color
    + +
    +
    + )} +
    +
    + ); +}; + +export default GlobalProperties; diff --git a/frontend/src/components/ui/sideBar/realTimeViz/chartComponent.tsx b/frontend/src/components/ui/sideBar/realTimeViz/chartComponent.tsx new file mode 100644 index 0000000..7065e72 --- /dev/null +++ b/frontend/src/components/ui/sideBar/realTimeViz/chartComponent.tsx @@ -0,0 +1,114 @@ +import React, { useEffect, useRef, useMemo } from "react"; +import { Chart, ChartType } from "chart.js/auto"; +import { useThemeStore, useWidgetStore } from "../../../../store/store"; + +interface ChartComponentProps { + type: ChartType; + title: string; + fontFamily?: string; + fontSize?: string; + fontWeight?: "Light" | "Regular" | "Bold"; // Explicitly typing fontWeight +} + +const ChartComponent = ({ + type, + title, + fontFamily, + fontSize, + fontWeight = "Regular", // Default to "Regular" +}: ChartComponentProps) => { + const canvasRef = useRef(null); + const { themeColor } = useThemeStore(); + + // Memoize theme colors to prevent unnecessary recalculations + const buttonActionColor = useMemo( + () => themeColor[0] || "#5c87df", + [themeColor] + ); + const buttonAbortColor = useMemo( + () => themeColor[1] || "#ffffff", + [themeColor] + ); + + // Memoize font weight mapping + const chartFontWeightMap = useMemo( + () => ({ + Light: "lighter" as const, + Regular: "normal" as const, + Bold: "bold" as const, + }), + [] + ); + + // Parse and memoize fontSize + const fontSizeValue = useMemo( + () => (fontSize ? parseInt(fontSize) : 12), + [fontSize] + ); + + // Determine and memoize font weight + const fontWeightValue = useMemo( + () => chartFontWeightMap[fontWeight], // No need for '|| "normal"' since fontWeight is guaranteed to be valid + [fontWeight, chartFontWeightMap] + ); + + // Memoize chart font style + const chartFontStyle = useMemo( + () => ({ + family: fontFamily || "Arial", + size: fontSizeValue, + weight: fontWeightValue, + }), + [fontFamily, fontSizeValue, fontWeightValue] + ); + + // Memoize chart data + const data = useMemo( + () => ({ + labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"], + datasets: [ + { + data: [65, 59, 80, 81, 56, 55, 40], + backgroundColor: buttonActionColor, + borderColor: buttonAbortColor, + borderWidth: 1, + }, + ], + }), + [buttonActionColor, buttonAbortColor] + ); + + // Memoize chart options + const options = useMemo( + () => ({ + responsive: true, + maintainAspectRatio: false, + plugins: { + title: { + display: true, + text: title, + font: chartFontStyle, + }, + legend: { + display: false, + }, + }, + }), + [title, chartFontStyle] + ); + + useEffect(() => { + if (!canvasRef.current) return; + + const ctx = canvasRef.current.getContext("2d"); + if (!ctx) return; + + const chart = new Chart(ctx, { type, data, options }); + + return () => chart.destroy(); + }, [type, data, options]); // Only recreate chart when these essentials change + + return ; +}; + +export default React.memo(ChartComponent); diff --git a/frontend/src/components/ui/sideBar/realTimeViz/data.tsx b/frontend/src/components/ui/sideBar/realTimeViz/data.tsx new file mode 100644 index 0000000..c786ae1 --- /dev/null +++ b/frontend/src/components/ui/sideBar/realTimeViz/data.tsx @@ -0,0 +1,147 @@ +import React, { useState } from "react"; +import RegularDropDown from "../../inputs/regularDropDown"; +import { LinkIcon, RemoveIcon } from "../../../../assets/images/svgExports"; + +interface Child { + id: number; + easing: string; +} + +interface Group { + id: number; + easing: string; + children: Child[]; +} + +const Data = () => { + const [selectedWidget] = useState("Widget 1"); + const [groups, setGroups] = useState([ + { + id: 1, + easing: "Connecter 1", + children: [ + { id: 1, easing: "Linear" }, + { id: 2, easing: "Linear" }, + { id: 3, easing: "Linear" }, + ], + }, + ]); + + const handleLinkClick = (childId: number) => { + setGroups((currentGroups) => { + let sourceGroup: Group | undefined; + let sourceChild: Child | undefined; + + // Find the source group and child + for (const group of currentGroups) { + sourceChild = group.children.find((c) => c.id === childId); + if (sourceChild) { + sourceGroup = group; + break; + } + } + + if (!sourceGroup || !sourceChild) return currentGroups; + + // Remove child from source group + const updatedGroups = currentGroups + .map((group) => ({ + ...group, + children: group.children.filter((c) => c.id !== childId), + })) + .filter((group) => group.children.length > 0); + + // Find or create target group + const targetGroup = updatedGroups.find( + (g) => g.id !== sourceGroup!.id && g.easing === sourceGroup!.easing + ); + + if (targetGroup) { + targetGroup.children.push(sourceChild); + } else { + updatedGroups.push({ + id: Date.now(), + easing: sourceGroup.easing, + children: [sourceChild], + }); + } + + return updatedGroups; + }); + }; + + const removeChild = (childId: number) => { + setGroups((groups) => + groups + .map((group) => ({ + ...group, + children: group.children.filter((c) => c.id !== childId), + })) + .filter((group) => group.children.length > 0) + ); + }; + + return ( +
    +
    {selectedWidget}
    + {groups.map((group, groupIndex) => ( +
    +
    + +
    Data from
    + { + setGroups( + groups.map((g) => (g.id === group.id ? { ...g, easing } : g)) + ); + }} + /> +
    + {group.children.map((child) => ( +
    +
    Input {child.id}
    + { + setGroups( + groups.map((g) => ({ + ...g, + children: g.children.map((c) => + c.id === child.id ? { ...c, easing } : c + ), + })) + ); + }} + /> +
    handleLinkClick(child.id)}> + +
    +
    removeChild(child.id)}> + +
    +
    + ))} +
    + ))} +
    + i +

    + + By adding templates and widgets, you create a customizable and + dynamic environment. + +

    +
    +
    + ); +}; + +export default Data; diff --git a/frontend/src/components/ui/sideBar/realTimeViz/design.tsx b/frontend/src/components/ui/sideBar/realTimeViz/design.tsx new file mode 100644 index 0000000..a1e29f7 --- /dev/null +++ b/frontend/src/components/ui/sideBar/realTimeViz/design.tsx @@ -0,0 +1,147 @@ +import React, { useEffect, useState } from "react"; +import RegularDropDown from "../../inputs/regularDropDown"; +import { useWidgetStore } from "../../../../store/store"; +import styles from "./Design.module.scss"; // Import SCSS file +import ChartComponent from "./chartComponent"; + +type Side = "top" | "bottom" | "left" | "right"; + +// Define the Widget interface +interface Widget { + id: string; + type: string; // Change this if the type is more specific + panel: Side; // You should define or import 'Side' type if not already defined + title: string; + fontFamily?: string; + fontSize?: string; + fontWeight?: string; +} + +const Design = () => { + const [selectedName, setSelectedName] = useState("drop down"); + const [selectedElement, setSelectedElement] = useState("drop down"); + const [selectedFont, setSelectedFont] = useState("drop down"); + const [selectedSize, setSelectedSize] = useState("drop down"); + const [selectedWeight, setSelectedWeight] = useState("drop down"); + + const { selectedChartId, setSelectedChartId, widgets, setWidgets } = + useWidgetStore(); // Get selected chart ID and list of widgets + + // Find the selected widget based on `selectedChartId` + const selectedWidget = selectedChartId + ? widgets.find((widget) => widget.id === selectedChartId.id) + : null; + + // Function to update the selected widget + const handleUpdateWidget = (updatedProperties: Partial) => { + if (!selectedWidget) { + return; + } + + // Update the widgets array + const updatedWidgets = widgets.map((widget) => + widget.id === selectedWidget.id + ? { ...widget, ...updatedProperties } // Merge existing widget with updated properties + : widget + ); + + // Update the global state with the new widgets array + setWidgets(updatedWidgets); + + // Update `selectedChartId` to reflect the changes + if (selectedChartId) { + const updatedChartId = { + ...selectedChartId, + ...updatedProperties, // Merge updated properties into `selectedChartId` + }; + setSelectedChartId(updatedChartId); + } + }; + + useEffect(() => { + // Log the current state of widgets for debugging + }, [widgets]); + + return ( +
    + {/* Display the selected widget's title */} +
    + {selectedWidget ? selectedWidget.title : "Widget 1"} +
    +
    + {/* Pass selectedWidget properties to ChartComponent */} + {selectedWidget && ( + + )} +
    + + {/* Design Options */} +
    +
    + Name + { + setSelectedName(value); + handleUpdateWidget({ title: value }); + }} + /> +
    + +
    + Element + { + setSelectedElement(value); + handleUpdateWidget({ type: value }); // Update element type + }} + /> +
    + +
    + Font Family + { + setSelectedFont(value); + handleUpdateWidget({ fontFamily: value }); + }} + /> +
    + +
    + Size + { + setSelectedSize(value); + handleUpdateWidget({ fontSize: value }); + }} + /> +
    + +
    + Weight + { + setSelectedWeight(value); + handleUpdateWidget({ fontWeight: value }); + }} + /> +
    +
    +
    + ); +}; + +export default Design; diff --git a/frontend/src/components/ui/sideBar/realTimeViz/overview.tsx b/frontend/src/components/ui/sideBar/realTimeViz/overview.tsx new file mode 100644 index 0000000..d21ef00 --- /dev/null +++ b/frontend/src/components/ui/sideBar/realTimeViz/overview.tsx @@ -0,0 +1,175 @@ +import React, { useState } from "react"; +import { + DropDownIcon, + EyeIcon, + LockIcon, + RecFocusIcon, + SearchIcon, + ThemeIcon, +} from "../../../../assets/images/svgExports"; + +interface Section { + title: string; + items: string[]; + isOpen: boolean; + selectedItem: number | null; +} + +const Overview = () => { + const [sections, setSections] = useState([ + { + title: "Layers", + items: ["Ground floor", "First floor"], + isOpen: false, + selectedItem: null, + }, + { + title: "Scene", + items: ["scene-1", "scene-2", "scene-3", "scene-4"], + isOpen: false, + selectedItem: null, + }, + ]); + + const [viewMode, setViewMode] = useState<"2D" | "3D">("2D"); + + // Handle item selection + const handleItemClick = (sectionIndex: number, itemIndex: number) => { + setSections((prevSections) => + prevSections.map((section, i) => + i === sectionIndex + ? { + ...section, + selectedItem: + section.selectedItem === itemIndex + ? section.selectedItem + : itemIndex, + } + : section + ) + ); + }; + + // Toggle section open or closed + const toggleSection = (sectionIndex: number) => { + setSections((prevSections) => + prevSections.map((section, i) => + i === sectionIndex ? { ...section, isOpen: !section.isOpen } : section + ) + ); + }; + + // Toggle between 2D and 3D views + const switchView = (mode: "2D" | "3D") => { + setViewMode(mode); + }; + + + return ( + <> +
    + {/* search-main-container */} +
    + {/* Search Input */} +
    +
    + +
    + +
    +
    +
    + + {/* Options & Theme */} +
    +
    + switchView("2D")} + > + 2D + + switchView("3D")} + > + 3D + +
    +
    + +
    + {/* {theme && ( +
    +

    Presets

    +
    + {preset.map((colors, index) => ( +
    setActivePresetIndex(index)} + > + {colors.map((color, i) => ( +
    + ))} +
    + ))} +
    +
    + )} */} +
    +
    +
    + +
    + {sections.map((section, sectionIndex) => ( +
    +
    toggleSection(sectionIndex)} + > +
    {section.title}
    +
    + + +
    +
    + + {section.isOpen && ( +
    + {section.items.map((item, itemIndex) => ( +
    handleItemClick(sectionIndex, itemIndex)} + > +
    {item}
    +
    + + +
    +
    + ))} +
    + )} +
    + ))} +
    + + ); +}; + +export default Overview; + +// diff --git a/frontend/src/components/ui/sideBar/realTimeViz/widgets.tsx b/frontend/src/components/ui/sideBar/realTimeViz/widgets.tsx new file mode 100644 index 0000000..de1a5c2 --- /dev/null +++ b/frontend/src/components/ui/sideBar/realTimeViz/widgets.tsx @@ -0,0 +1,198 @@ +import React, { useState, useEffect, useRef } from "react"; +import { useThemeStore, useWidgetStore } from "../../../../store/store"; +import { ChartType } from "chart.js/auto"; +import ChartComponent from "./chartComponent"; +import { + DropDownIcon, + SearchIcon, + ThemeIcon, +} from "../../../../assets/images/svgExports"; +import RegularDropDown from "../../inputs/regularDropDown"; + +const Widgets = () => { + const chartTypes: ChartType[] = [ + "bar", + "line", + "pie", + "doughnut", + "radar", + "polarArea", + ]; + + const { setDraggedAsset } = useWidgetStore((state) => state); + const [selectedValue, setSelectedValue] = useState(null); + const [viewMode, setViewMode] = useState<"2D" | "3D" | "Floating">("2D"); + + const switchView = (mode: "2D" | "3D" | "Floating") => { + setViewMode(mode); + }; + + const { themeColor, setThemeColor } = useThemeStore(); + const [theme, setTheme] = useState(false); // Default is false + const [activePresetIndex, setActivePresetIndex] = useState( + null + ); + const [customColor, setCustomColor] = useState("#000000"); + + const themeContainerRef = useRef(null); + + const preset = [ + ["#6F42C1", "#EEEEFE", "#B392F0"], + ["#F8CB47", "#F79002", "#F73F65"], + ["#FDA4B8", "#FF6A90", "#B91348"], + ["#D1BCF6", "#987BEB", "#6443C9"], + ["#FDC64B", "#EF9407", "#B54300"], + ["#69E9AB", "#0BB96E", "#087348"], + ["#85ADFC", "#246FFE", "#0050EB"], + ["#F570C7", "#27CEF7", "#FFAD1A"], + ["#6572F2", "#EE42B7", "#12B56E"], + ["#10BA68", "#FDB022", "#EA48B5"], + ["#10BA68", "#FDB022", "#EA48B5"], + ["#6F42C1", "#CEB2F6", "#EA48B5"], + ]; + + // Close theme container on outside click + useEffect(() => { + const themBtn = document.querySelector(".theme-switch"); + + const handleClickOutside = (event: MouseEvent) => { + // Check if the click is outside the theme container or theme button + if ( + themeContainerRef.current && + !themeContainerRef.current.contains(event.target as Node) && + !themBtn?.contains(event.target as Node) // Ensure that the click is not inside the theme button + ) { + setTheme(false); // Close the theme container when clicking outside + } + }; + + document.addEventListener("mousedown", handleClickOutside); + + return () => { + document.removeEventListener("mousedown", handleClickOutside); // Cleanup event listener on unmount + }; + }, []); + + useEffect(() => {}, [theme]); + + return ( +
    + {/* Search Container */} +
    +
    +
    + +
    + +
    +
    +
    + + {/* Options and Theme Management */} +
    +
    + switchView("2D")} + > + 2D + + switchView("3D")} + > + 3D + + switchView("Floating")} + > + Floating + +
    + + {/* Theme Switcher */} +
    setTheme(!theme)} // Toggle the theme container + > + +
    + + {/* Theme Presets */} + {theme && ( +
    +

    Presets

    +
    + {preset.map((colors, index) => ( +
    { + setThemeColor(colors); + setActivePresetIndex(index); + }} + > + {colors.map((color, i) => ( +
    + ))} +
    + ))} +
    +
    +

    Custom Color

    +
    + { + const newColor = e.target.value; + setCustomColor(newColor); + setThemeColor([newColor, newColor, newColor]); + }} + /> + {customColor} +
    +
    +
    + )} +
    +
    + + {/* Chart Widgets */} +
    + {chartTypes.map((type, index) => { + const widgetTitle = `Widget ${index + 1}`; + return ( +
    { + setDraggedAsset({ + type, + id: `widget-${index + 1}`, + title: widgetTitle, + }); + }} + onDragEnd={() => setDraggedAsset(null)} + > + +
    + ); + })} +
    +
    + ); +}; + +export default Widgets; diff --git a/frontend/src/components/ui/toolBar/toolBar.tsx b/frontend/src/components/ui/toolBar/toolBar.tsx new file mode 100644 index 0000000..d6deefa --- /dev/null +++ b/frontend/src/components/ui/toolBar/toolBar.tsx @@ -0,0 +1,173 @@ +import React, { useState, useEffect } from "react"; +import { + CursorIcon, + ScaleIcon, + RotateIcon, + MoveIcon, + DrawWallIcon, + DrawZoneIcon, + DrawAsileIcon, + AddPillerIcon, + DrawOnlyFloorIcon, + DeleteToolIcon, + MesureIcon, +} from "../../../assets/images/svgExports"; + +import { + useDeletePointOrLine, + useMovePoint, + useToggleView, + useSelectedWallItem, + useAddAction, + useDeleteModels, + useTransformMode, + useActiveTool, + useToolMode +} from "../../../store/store"; + +const ToolBar: React.FC = () => { + const { toggleView, setToggleView } = useToggleView(); + const { deleteModels, setDeleteModels } = useDeleteModels(); + const { transformMode, setTransformMode } = useTransformMode(); + const { deletePointOrLine, setDeletePointOrLine } = useDeletePointOrLine(); + const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem(); + const { addAction, setAddAction } = useAddAction(); + const { movePoint, setMovePoint } = useMovePoint(); + const { toolMode, setToolMode } = useToolMode(); + const { activeTool, setActiveTool } = useActiveTool(); + const [AddModel, setAddModel] = useState(false); + + useEffect(() => { + setActiveTool("Cursor"); + setTransformMode(null); + }, [toggleView]); + + const handleToolClick = (toolAction: string) => { + setToolMode(null); + setDeleteModels(false); + setAddAction(null); + setTransformMode(null); + setMovePoint(false); + setDeletePointOrLine(false); + + switch (toolAction) { + case "Move": + if (toggleView) { + setMovePoint(true); + } else { + setTransformMode("translate"); + } + break; + + case "Rotate": + if (!toggleView) { + setTransformMode("rotate"); + } + break; + + case "Scale": + if (!toggleView) { + setTransformMode("scale"); + } + break; + + case "Draw wall": + if (toggleView) { + setToolMode("Wall"); + } + break; + + case "Draw Aisle": + if (toggleView) { + setToolMode("Aisle"); + } + break; + + case "Mark zone": + if (toggleView) { + setToolMode("Zone"); + } + break; + + case "Draw Floor": + if (toggleView) { + setToolMode("Floor"); + } + break; + + case "Measurement Tool": + setToolMode("MeasurementScale"); + break; + + case "Add pillar": + if (!toggleView) { + setAddModel(false); + setAddAction("pillar"); + } + break; + + case "Delete": + if (toggleView) { + setDeletePointOrLine(true); + } else { + setAddModel(false); + setDeleteModels(true); + } + break; + + default: + break; + } + + setActiveTool(toolAction); + }; + + + const tools = [ + { icon: CursorIcon, name: "Cursor", availableMode: "always" }, + { icon: ScaleIcon, name: "Scale", availableMode: "only_3d" }, //transform tools + { icon: RotateIcon, name: "Rotate", availableMode: "only_3d" }, //transform tools + { icon: MoveIcon, name: "Move", availableMode: "always" }, //transform tools + { icon: DrawWallIcon, name: "Draw wall", availableMode: "only_2d" }, + { icon: DrawZoneIcon, name: "Mark zone", availableMode: "only_2d" }, + { icon: DrawAsileIcon, name: "Draw Aisle", availableMode: "only_2d" }, + { icon: AddPillerIcon, name: "Add pillar", availableMode: "only_3d" }, + { icon: DrawOnlyFloorIcon, name: "Draw Floor", availableMode: "only_2d" }, + { icon: MesureIcon, name: "Measurement Tool", availableMode: "always" }, + { icon: DeleteToolIcon, name: "Delete", availableMode: "always" }, + ]; + + return ( + <> +
    + {tools.map((tool, index) => { + if (toggleView && (tool.availableMode === "always" || tool.availableMode === "only_2d")) { + return ( +
    handleToolClick(tool.name)} + > + +
    {tool.name}
    +
    + ); + } else if (!toggleView && (tool.availableMode === "always" || tool.availableMode === "only_3d")) { + return ( +
    handleToolClick(tool.name)} + > + +
    {tool.name}
    +
    + ); + } + })} +
    + + ); +}; + +export default ToolBar; diff --git a/frontend/src/components/ui/uitemp/Images/arch.png b/frontend/src/components/ui/uitemp/Images/arch.png new file mode 100644 index 0000000..1bb8976 Binary files /dev/null and b/frontend/src/components/ui/uitemp/Images/arch.png differ diff --git a/frontend/src/components/ui/uitemp/Images/beanbag.png b/frontend/src/components/ui/uitemp/Images/beanbag.png new file mode 100644 index 0000000..5c23925 Binary files /dev/null and b/frontend/src/components/ui/uitemp/Images/beanbag.png differ diff --git a/frontend/src/components/ui/uitemp/Images/door.png b/frontend/src/components/ui/uitemp/Images/door.png new file mode 100644 index 0000000..c537d2a Binary files /dev/null and b/frontend/src/components/ui/uitemp/Images/door.png differ diff --git a/frontend/src/components/ui/uitemp/Images/sofa.png b/frontend/src/components/ui/uitemp/Images/sofa.png new file mode 100644 index 0000000..26aad4c Binary files /dev/null and b/frontend/src/components/ui/uitemp/Images/sofa.png differ diff --git a/frontend/src/components/ui/uitemp/Images/window.png b/frontend/src/components/ui/uitemp/Images/window.png new file mode 100644 index 0000000..60d853c Binary files /dev/null and b/frontend/src/components/ui/uitemp/Images/window.png differ diff --git a/frontend/src/components/ui/uitemp/layers.tsx b/frontend/src/components/ui/uitemp/layers.tsx new file mode 100644 index 0000000..b14bf5c --- /dev/null +++ b/frontend/src/components/ui/uitemp/layers.tsx @@ -0,0 +1,133 @@ +import { useState, useEffect } from "react"; +import { useToggleView, useRemoveLayer, useActiveLayer, useRemovedLayer, useLayers } from "../../../store/store"; +import { getLines } from "../../../services/factoryBuilder/lines/getLinesApi"; + +// Defining the Layers component +function Layers() { + // Hook to get and set the toggleView state from the store + const { toggleView } = useToggleView(); + + // Hook to get and set the removeLayer state from the store + const { removeLayer, setRemoveLayer } = useRemoveLayer(); + + // Hook to get and set the removedLayer state from the store + const { removedLayer, setRemovedLayer } = useRemovedLayer(); + + // Hook to get and set the ActiveLayer state from the store + const { activeLayer, setActiveLayer } = useActiveLayer(); + + const { Layers, setLayers } = useLayers(); + + + useEffect(() => { + const email = localStorage.getItem('email') + if (!email) return; + const organization = (email!.split("@")[1]).split(".")[0]; + + // Load data from localStorage if available + getLines(organization).then((data) => { + if (data.length === 0) { + setLayers(1); + } else { + setLayers(data.reduce((max: any, item: any) => Math.max(max, item.layer), -Infinity)); + } + }) + }, []) + + // Function to handle the addition of a new layer + function handleAddLayer() { + // Calculate new layer number based on the maximum existing layer number + let arr = Array.from({ length: Layers }, (_, index) => index + 1) + const newLayer = arr.length ? Math.max(...arr) + 1 : 1; + // console.log('newLayer: ', newLayer); + setLayers(newLayer); + } + + // Function to handle the removal of a layer + function handleRemoveLayer(layerToRemove: number) { + // Prevent removing the last layer or the base layer (layer 1) + let arr = Array.from({ length: Layers }, (_, index) => index + 1) + if (arr.length <= 1 || layerToRemove === 1) { + return; + } + + // Remove the selected layer and re-number remaining Layers + const updatedLayers = arr.filter(layer => layer !== layerToRemove); + const renumberedLayers = updatedLayers.map((_, index) => index + 1); + + // Update the Layers and sync with localStorage + setLayers(renumberedLayers.length); + + // Update the removed layer and reset active layer to 1 + setRemovedLayer(layerToRemove); + setActiveLayer(1); + } + + // Function to toggle the removeLayer mode + function toggleRemoveLayer() { + setRemoveLayer(!removeLayer); + } + + // Function to handle when a layer is clicked, setting it as the active layer + function handleLayerClick(layer: number) { + setActiveLayer(layer); + } + + // useEffect to reset the remove layer mode and active layer to defaults when toggleView changes + useEffect(() => { + setRemoveLayer(false); + setActiveLayer(1); + }, [toggleView]); + + // Render the component JSX + return ( + <> + {toggleView && ( + <> + {/* Buttons for adding Layers and toggling remove mode */} +
    + + +
    + + {/* Render the Layers */} +
    + {Array.from({ length: Layers }, (_, index) => index + 1).map((layer, index) => ( +
    + {/* Button to set a layer as the active layer */} + + + {/* If removeLayer mode is active, show a delete button next to each layer */} + {removeLayer && ( + + )} +
    + ))} +
    + + )} + + ); +} + +export default Layers; diff --git a/frontend/src/components/ui/uitemp/scale.tsx b/frontend/src/components/ui/uitemp/scale.tsx new file mode 100644 index 0000000..11ace32 --- /dev/null +++ b/frontend/src/components/ui/uitemp/scale.tsx @@ -0,0 +1,86 @@ +// import * as THREE from "three"; +// import { useState, useEffect } from "react"; +// import { usesetScale, useWallItemsState, useselectedWallItem } from "../../../store/store"; + +// Define the shape of WallItem type based on your current usage +// type WallItem = { +// model: { parent: { uuid: string } }; +// scale: number[]; +// // Add other properties as needed +// }; + +// Define the Scale component +function Scale() { + // Retrieve selectedWallItem, setselectedWallItem, WallItemsState, setWallItemsState, Scale, and setScale from custom hooks in the store + // const { selectedWallItem, setselectedWallItem } = useselectedWallItem(); + // const { WallItemsState, setWallItemsState } = useWallItemsState(); + // const { Scale, setScale } = usesetScale(); + + // // Effect to update the scale when selectedWallItem changes + // useEffect(() => { + // if (selectedWallItem) { + // // Set the scale to the selectedWallItem's parent scale + // setScale(selectedWallItem.parent.scale); + // } + // }, [selectedWallItem]); + + // // Function to handle changes to the width + // function onWidthChange(event: React.ChangeEvent) { + // const newWidth = parseFloat(event.target.value); + + // // Update the scale in the state and apply it to the selectedWallItem + // setScale(new THREE.Vector3(newWidth, Scale.y, Scale.z)); + // selectedWallItem.scale.set(newWidth, Scale.y, Scale.z); + + // let ScaledWallItems: WallItem[] = []; // Explicitly define the type + + // // Update the WallItemsState to reflect the new scale + // WallItemsState.forEach((items: WallItem) => { + // if (items.model.parent.uuid === selectedWallItem.uuid) { + // items.scale = [newWidth, Scale.y, Scale.z]; + // } + // ScaledWallItems.push(items); + // }); + + // // Save the updated WallItems to localStorage without the model property + // const WallItemsForStorage = ScaledWallItems.map((item) => { + // const { model, ...rest } = item; + // return rest; + // }); + // localStorage.setItem("WallItems", JSON.stringify(WallItemsForStorage)); + // } + + // // Function to handle changes to the height + // function onHeigthChange(event: React.ChangeEvent) { + // const newHeight = parseFloat(event.target.value); + + // // Update the scale in the state and apply it to the selectedWallItem + // setScale(new THREE.Vector3(Scale.x, newHeight, Scale.z)); + // selectedWallItem.scale.set(Scale.x, newHeight, Scale.z); + + // let ScaledWallItems: WallItem[] = []; // Explicitly define the type + + // // Update the WallItemsState to reflect the new scale + // WallItemsState.forEach((items: WallItem) => { + // if (items.model.parent.uuid === selectedWallItem.uuid) { + // items.scale = [Scale.x, newHeight, Scale.z]; + // } + // ScaledWallItems.push(items); + // }); + + // // Save the updated WallItems to localStorage without the model property + // const WallItemsForStorage = ScaledWallItems.map((item) => { + // const { model, ...rest } = item; + // return rest; + // }); + // localStorage.setItem("WallItems", JSON.stringify(WallItemsForStorage)); + // } + + // Render the component JSX + return ( + <> + + ); +} + +export default Scale; diff --git a/frontend/src/components/ui/uitemp/ui.tsx b/frontend/src/components/ui/uitemp/ui.tsx new file mode 100644 index 0000000..4688319 --- /dev/null +++ b/frontend/src/components/ui/uitemp/ui.tsx @@ -0,0 +1,269 @@ +import React, { useState, useEffect } from "react"; +import { + useToggleView, + use2DUndoRedo, + useDeletePointOrLine, + useMovePoint, + useDeleteModels, + useSelectedWallItem, + useRoofVisibility, + useWallVisibility, + useResetCamera, + useAddAction, + useCamMode +} from "../../../store/store"; // Importing custom hooks from the store for state management +import image1 from './Images/sofa.png'; +import image2 from './Images/beanbag.png'; +import image3 from './Images/arch.png'; +import image4 from './Images/window.png'; +import image5 from './Images/door.png'; + +import { ToastContainer } from 'react-toastify'; +import 'react-toastify/dist/ReactToastify.css'; + +import Scale from "./scale"; // Component for scaling +import Layers from "./layers"; // Component for layers management + +const UI: React.FC = () => { + // State management hooks + const { ToggleView, setToggleView } = useToggleView(); + const { DeleteModels, setDeleteModels } = useDeleteModels(); + const { camMode, setCamMode } = useCamMode(); + const { ResetCamera, setResetCamera } = useResetCamera(); + const { AddAction, setAddAction } = useAddAction(); + const { roofVisibility, setRoofVisibility } = useRoofVisibility(); + const { wallVisibility, setWallVisibility } = useWallVisibility(); + + // Local state to manage active button and model visibility + const [activeButton, setActiveButton] = useState(null); + const [AddModel, setAddModel] = useState(false); + + // State management for different functionalities + const { MoveWall, setMoveWall } = useMovePoint(); + const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem(); + const { deletePointOrLine, setDeletePointOrLine } = useDeletePointOrLine(); + const { is2DUndoRedo, set2DUndoRedo } = use2DUndoRedo(); + + // Function to handle view change + // const Change = () => { + // setSelectedWallItem(null); // Clear selected wall item + // setAddModel(false); // Hide model adding interface + // setDeleteModels(false); // Hide delete model interface + // setAddAction(null); // Hide add pillar interface + // setToggleView(!ToggleView); // Toggle view state + // setActiveButton(null); // Reset active button + // }; + + // // Function to set floor change + // const Set = () => { + // setFloorChange(true); // Trigger floor change + // setActiveButton(null); // Reset active button + // }; + + // // Function to toggle drawing mode + // const Draw = () => { + // setDrawWall(!DrawWall); // Toggle drawing walls + // setActiveButton(activeButton !== 'draw' ? 'draw' : null); // Set active button state + // }; + + // // Function to toggle floor drawing mode + // const drawOnlyFloor = () => { + // setDrawOnlyFloor(!DrawOnlyFloor); // Toggle drawing only the floor + // setActiveButton(activeButton !== 'drawOnlyFloor' ? 'drawOnlyFloor' : null); // Set active button state + // }; + + // // Function to toggle floor deletion mode + // const Deletefloor = () => { + // setDeletePointOrLine(!deletePointOrLine); // Toggle point/line deletion + // setActiveButton(activeButton !== 'delete' ? 'delete' : null); // Set active button state + // }; + + // // Function to toggle wall moving mode + // const Movefloor = () => { + // setMoveWall(!MoveWall); // Toggle moving walls + // setActiveButton(activeButton !== 'move' ? 'move' : null); // Set active button state + // }; + + // Effect to reset active button if no drawing actions are active + // useEffect(() => { + // if (!DrawWall && !deletePointOrLine && !MoveWall && !DrawOnlyFloor) { + // setActiveButton(null); + // } + // }, [DrawWall, DrawOnlyFloor]); + + // Load roof visibility from local storage on component mount + // useEffect(() => { + // const roofVisibility = JSON.parse(localStorage.getItem("Visibility")!).roofVisibility; + // if (JSON.parse(localStorage.getItem("Visibility")!).roofVisibility === true) { + // setRoofVisibility(roofVisibility); + // } + // }, []); + + // // Load wall visibility from local storage on component mount + // useEffect(() => { + // const wallVisibility = JSON.parse(localStorage.getItem("Visibility")!).wallVisibility; + // if (JSON.parse(localStorage.getItem("Visibility")!).wallVisibility === true) { + // setWallVisibility(wallVisibility); + // } + // }, []); + + useEffect(() => { + if (!ToggleView) { + setActiveButton(null); + } + }, [ToggleView]) + + // Save roof and wall visibility to local storage whenever it changes + // useEffect(() => { + // localStorage.setItem("Visibility", JSON.stringify({ "roofVisibility": roofVisibility, "wallVisibility": wallVisibility })); + // }, [roofVisibility, wallVisibility]); + + // Function to toggle model adding interface + const addModel = () => { + setSelectedWallItem(null); // Clear selected wall item + setDeleteModels(false); // Hide delete model interface + setAddAction(null); // Hide add pillar interface + setAddModel(!AddModel); // Toggle add model interface + setActiveButton(activeButton !== 'addmodels' ? 'addmodels' : null); // Set active button state + }; + + // // Function to toggle model deletion interface + // const deleteModel = () => { + // setSelectedWallItem(null); // Clear selected wall item + // setAddModel(false); // Hide add model interface + // setAddAction(null); // Hide add pillar interface + // setDeleteModels(!DeleteModels); // Toggle delete model interface + // setActiveButton(activeButton !== 'deletemodels' ? 'deletemodels' : null); // Set active button state + // }; + + // // Function to toggle add pillar mode + // const addPillar = () => { + // setSelectedWallItem(null); // Clear selected wall item + // setAddModel(false); // Hide add model interface + // setDeleteModels(false); // Hide delete model interface + // // setAddAction(!AddAction); // Toggle add pillar mode + // setActiveButton(activeButton !== 'addPillar' ? 'addPillar' : null); // Set active button state + // }; + + // // Function to reset camera + // const resetCamera = () => { + // setResetCamera(true); // Trigger reset camera action + // }; + + // // Function to clear local storage + // const clearStorage = () => { + // setSelectedWallItem(null); // Clear selected wall item + // localStorage.setItem("Lines", JSON.stringify([])); // Clear lines + // localStorage.setItem("WallItems", JSON.stringify([])); // Clear wall items + // localStorage.setItem("FloorItems", JSON.stringify([])); // Clear floor items + // localStorage.setItem("FloorLines", JSON.stringify([])); // Clear floor lines + // }; + + // // Function to toggle roof visibility + // const roofVisibiliy = () => { + // setRoofVisibility(!roofVisibility); // Toggle roof visibility + // }; + + // // Function to toggle wall visibility + // const wallVisibility = () => { + // setWallVisibility(!wallVisibility); // Toggle wall visibility + // }; + + // function Undo() { + // set2DUndoRedo("Undo"); + // } + + // function Redo() { + // set2DUndoRedo("Redo"); + // } + + // const clearCacheData = () => { + // caches.keys().then((names) => { + // names.forEach((name) => { + // caches.delete(name); + // }); + // }); + // alert("Complete Cache Cleared"); + // }; + + // Render UI components + return ( +
    e.stopPropagation()}> + {/*
    + {!ToggleView ? ( + + ) : ( + + )} + {ToggleView && } +
    */} + {/*
    + {ToggleView && } + {ToggleView && } +
    */} + {/*
    + {ToggleView && } + {ToggleView && } +
    */} + {/*
    + {ToggleView && } + {ToggleView && } +
    */} + {/*
    + +
    */} +
    + {!ToggleView && } + {!ToggleView && AddModel && ( +
    +
    + +
    +
    + +
    +
    + +
    +
    + )} +
    + {/*
    + {!ToggleView && } +
    */} + {/*
    + {!ToggleView && } +
    */} + {/*
    + {!ToggleView && } +
    */} + {/*
    + {!ToggleView && } +
    */} + {/* {!ToggleView && ( +
    + Roof Visibility + +
    + )} + {!ToggleView && ( +
    + Wall Visibility + +
    + )} */} + {/* Scale component */} + {/* Layers component */} +
    + ); +} + +export default UI; diff --git a/frontend/src/components/ui/undoRedo/undoRedo.tsx b/frontend/src/components/ui/undoRedo/undoRedo.tsx new file mode 100644 index 0000000..4622236 --- /dev/null +++ b/frontend/src/components/ui/undoRedo/undoRedo.tsx @@ -0,0 +1,28 @@ +import { UndoLeft, UndoRight } from "../../../assets/images/svgExports"; + +import { use2DUndoRedo } from "../../../store/store"; + +const UndoRedo = () => { + const { is2DUndoRedo, set2DUndoRedo } = use2DUndoRedo(); + + function Undo() { + set2DUndoRedo("Undo"); + } + + function Redo() { + set2DUndoRedo("Redo"); + } + return ( +
    +
    + +
    +
    +
    + +
    +
    + ); +}; + +export default UndoRedo; diff --git a/frontend/src/components/ui/wallTools/canvasTools.tsx b/frontend/src/components/ui/wallTools/canvasTools.tsx new file mode 100644 index 0000000..45021ff --- /dev/null +++ b/frontend/src/components/ui/wallTools/canvasTools.tsx @@ -0,0 +1,58 @@ +import React from "react"; +import { + DeleteIcon, + FlipIcon, + FlipIcon2, + FlipIcon3, + FocusIcon, + FreeIcon, + RenameIcon, +} from "../../../assets/images/svgExports"; + +const CanvasTools = () => { + return ( +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + ); +}; + +export default CanvasTools; + + diff --git a/frontend/src/functions/note.txt b/frontend/src/functions/note.txt new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/hooks/note.txt b/frontend/src/hooks/note.txt new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/index.css b/frontend/src/index.css new file mode 100644 index 0000000..ec2585e --- /dev/null +++ b/frontend/src/index.css @@ -0,0 +1,13 @@ +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/frontend/src/index.tsx b/frontend/src/index.tsx new file mode 100644 index 0000000..8bcb621 --- /dev/null +++ b/frontend/src/index.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import './index.css'; +import App from './app'; +import reportWebVitals from './reportWebVitals'; + +const root = ReactDOM.createRoot( + document.getElementById('root') as HTMLElement +); +root.render( + + + +); + +// If you want to start measuring performance in your app, pass a function +// to log results (for example: reportWebVitals(console.log)) +// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals +reportWebVitals(); diff --git a/frontend/src/logo.svg b/frontend/src/logo.svg new file mode 100644 index 0000000..9dfc1c0 --- /dev/null +++ b/frontend/src/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/modules/factory-builder/note.txt b/frontend/src/modules/factory-builder/note.txt new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/modules/process-creater/note.txt b/frontend/src/modules/process-creater/note.txt new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/modules/realtime-visualization/note.txt b/frontend/src/modules/realtime-visualization/note.txt new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/modules/simulation/note.txt b/frontend/src/modules/simulation/note.txt new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/pages/dashboard/note.txt b/frontend/src/pages/dashboard/note.txt new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/pages/note.txt b/frontend/src/pages/note.txt new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/pages/project/note.txt b/frontend/src/pages/project/note.txt new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/pages/project/popUp/collabPopUp.jsx b/frontend/src/pages/project/popUp/collabPopUp.jsx new file mode 100644 index 0000000..61285e7 --- /dev/null +++ b/frontend/src/pages/project/popUp/collabPopUp.jsx @@ -0,0 +1,192 @@ +import { useEffect, useRef, useState } from "react"; +// import { useSceneID, useSelectedUsersStore } from "../../../store"; +import RemoveUserPopUp from "./removeUserPopUp"; +import fetchShareUsers from "../../../services/factoryBuilder/collab/getUsersApi"; +import giveCollabAccess from "../../../services/factoryBuilder/collab/giveCollabAccess"; +import { toast } from "react-toastify"; +// import DropDown from "../dropdowns/dropdown"; +// import { fetchUserEmails } from "../../../services/apiService"; + +export default function CollabSettings({ setPopupCollab }) { + const [removeUser, setRemoveUser] = useState(false); + const [tempUsers, setTempUsers] = useState([]); + const [selectedUsers, setSelectedUsers] = useState([]); + const [arr, setArr] = useState(tempUsers); + const [search, setSearch] = useState(false); + const [removeID, setRemoveID] = useState(null); + // const { sceneId, setSceneId } = useSceneID(); + const [searchedEmail, setsearchedEmail] = useState(); + const [categories, setCategories] = useState([ + "All", + "Machine", + "Box", + "Buttons", + "Arm", + ]); + const [activeDrop, setActiveDrop] = useState(categories[0]); + + // State to manage permissions + const [userPermissions, setUserPermissions] = useState({}); + + let inputRef = useRef(); + + useEffect(() => { + const email = localStorage.getItem('email') + const organization = (email.split("@")[1]).split(".")[0]; + fetchShareUsers(organization) + .then((e) => { + if (e.message = "scene shared datas") { + const data = e.data; + const shared = data.filter(item => item.isShare); + setsearchedEmail(shared) + const notShared = data.filter(item => !item.isShare); + setsearchedEmail(notShared) + } + }) + + }, []); + + function handleClickAdd(name) { + inputRef.current.value = name; + } + + + function giveAccess(email) { + if (!email) return; + const organization = (email.split("@")[1]).split(".")[0]; + giveCollabAccess(email, true, organization) + .then((e) => { + toast.success("Shared succesfully") + fetchShareUsers(organization) + .then((e) => { + if (e.message = "scene shared datas") { + const data = e.data; + const shared = data.filter(item => item.isShare); + setsearchedEmail(shared) + const notShared = data.filter(item => !item.isShare); + setsearchedEmail(notShared) + } + }) + + }) + } + + return ( + <> + {removeUser && ( + + )} + {!removeUser && ( +
    +
    +
    +
    +

    Collaboration Settings

    +
    +
    setPopupCollab(false)} + > + X +
    +
    +
    +

    + This Project is private; only users listed below can access this + Layout. +

    +
    +
    + { + // }} + /> + + {inputRef.current?.value && search && ( +
    + {arr.map((val, i) => ( +
    { + // }} + > +
    {val[0]}
    +

    {val}

    +
    + ))} +
    + )} + { + giveAccess(inputRef.current?.value); + }} + type="submit" className="addMember" value="Add Members" /> + +
    + + {searchedEmail?.map((val, i) => ( +
    +
    handleClickAdd(val.email)}>{val.email}
    +
    + ))} +
    +
    + {selectedUsers.length > 0 ? ( +
    + {selectedUsers.map((email, i) => ( +
    +
    +
    + {email[0]} +
    +

    {email}

    +
    +
    +
    +
    + {/* + handlePermissionChange(email, permission) + } + /> */} +
    +
    +
    { + }} + > + Remove +
    +
    +
    + ))} +
    + ) : ( +
    Add Users to Collaborate
    + )} +
    +
    +
    +
    + )} + + ); +} \ No newline at end of file diff --git a/frontend/src/pages/project/popUp/removeUserPopUp.jsx b/frontend/src/pages/project/popUp/removeUserPopUp.jsx new file mode 100644 index 0000000..f1e0be0 --- /dev/null +++ b/frontend/src/pages/project/popUp/removeUserPopUp.jsx @@ -0,0 +1,75 @@ +import React from "react"; +// import { useSceneID, useSelectedUsersStore } from "../../../store"; + +export default function RemoveUserPopUp({ + setRemoveUser, + removeID, + setRemoveID, +}) { + // const { selectedUsers, setSelectedUsers } = useSelectedUsersStore(); + // const { sceneId, setSceneId } = useSceneID(); + function handleRemoveMembers() { + // fetch(`http://192.168.0.103:3502/api/v1/delete/${sceneId}`, { + // method: "POST", + // headers: { + // "Content-Type": "application/json", + // Authorization: `Bearer ${localStorage.getItem("token")}`, + // }, + // body: JSON.stringify({ + // Deletemail: selectedUsers[removeID], + // domain: "factory", + // }), + // }) + // .then((res) => res.json()) + // .then((res) => { + // console.log("res: ", res); + // if (res.message === "Deleted successfully") { + // setRemoveUser(false); + // selectedUsers.splice(removeID, 1); + // setSelectedUsers(selectedUsers); + // setRemoveID(null); + // } + // }) + // .catch((error) => { + // console.log("error: ", error); + // }); + } + + return ( +
    +
    +
    +
    + {/* */} +

    Are you sure?

    +
    +
    +
    + {/*

    + {`Are you sure you want to remove ${selectedUsers[removeID]}? They may not + be able to access this file anymore.`} +

    */} +
    +
    + { + // setRemoveUser(false); + // setRemoveID(null); + // }} + /> + +
    +
    +
    + ); +} \ No newline at end of file diff --git a/frontend/src/pages/project/project.tsx b/frontend/src/pages/project/project.tsx new file mode 100644 index 0000000..799b0d6 --- /dev/null +++ b/frontend/src/pages/project/project.tsx @@ -0,0 +1,114 @@ +import React, { useEffect, useRef, useState } from "react"; +import Header from "../../components/layout/header"; +import SideBar from "../../components/layout/sideBar"; +import SideBarLF from "../../components/layout/sideBarLayout2"; +import ToggleSwitch from "../../components/ui/inputs/toggleSwitch"; +import UndoRedo from "../../components/ui/undoRedo/undoRedo"; +import DropDown from "../../components/ui/inputs/dropDown"; +import { UploadIcon } from "../../assets/images/svgExports"; +import ToolBar from "../../components/ui/toolBar/toolBar"; +import Footer from "../../components/layout/footer"; +// import CanvasTools from "../../components/ui/wallTools/canvasTools"; +import ContextMenu from "../../components/ui/contextMenu/contextMenu"; +import RenderOverlay from "../../components/templates/overlay"; +import Scene from "../../components/scene/scene"; +import UI from "../../components/ui/uitemp/ui"; +import { + useOrganization, + useUserName, + useSocketStore, + useFloorItems, + useWallItems, +} from "../../store/store"; +import { useNavigate } from "react-router-dom"; +import RealTimeVisualization from "../realTimeVisualization/realTimeVisualization"; + +// Define the Project component +const Project: React.FC = () => { + let navigate = useNavigate(); + const switchesRef = useRef(null); + const [activeMenu, setActiveMenu] = useState("Realtime visualization"); + const { userName, setUserName } = useUserName(); + const { organization, setOrganization } = useOrganization(); + const { setFloorItems } = useFloorItems(); + const { setWallItems } = useWallItems(); + + useEffect(() => { + setFloorItems([]); + setWallItems([]); + const email = localStorage.getItem("email"); + if (email) { + useSocketStore.getState().initializeSocket(email); + const Organization = email!.split("@")[1].split(".")[0]; + const name = localStorage.getItem("userName"); + if (Organization && name) { + setOrganization(Organization); + setUserName(name); + } + } else { + navigate("/"); + } + }, []); + + // Handler for dropdown changes + const handleDropDownChange = (newValue: string) => {}; + + return ( +
    +
    + {/* factory builder */} + {activeMenu === "Factory builder" && ( +
    + + +
    + {/* Canvas container for rendering elements, uses the switchesRef */} +
    + + + + +
    + +
    +
    + + + +
    + + {/*
    + + Upload DXF + +
    */} +
    + + +
    + + {/* Sidebar on the right side with sections "Object" and "Material" */} + {activeMenu === "Factory builder" ? ( + + ) : ( + + )} + {/* Toolbar on the right side of the screen */} + +
    + )} + {/* realTime Viz */} + {activeMenu === "Realtime visualization" && } +
    +
    + ); +}; + +export default Project; diff --git a/frontend/src/pages/realTimeVisualization/realTimeVisualization.tsx b/frontend/src/pages/realTimeVisualization/realTimeVisualization.tsx new file mode 100644 index 0000000..385e660 --- /dev/null +++ b/frontend/src/pages/realTimeVisualization/realTimeVisualization.tsx @@ -0,0 +1,274 @@ +import React, { useEffect, useMemo, useState } from "react"; +import { + DndContext, + closestCenter, + KeyboardSensor, + PointerSensor, + useSensor, + useSensors, +} from "@dnd-kit/core"; +import { + SortableContext, + useSortable, + verticalListSortingStrategy, + arrayMove, +} from "@dnd-kit/sortable"; + +import { useWidgetStore } from "../../store/store"; // Assuming you have this store +import ChartComponent from "../../components/ui/sideBar/realTimeViz/chartComponent"; // Assuming this exists +import SideBar from "../../components/layout/sideBar"; // Assuming this exists +import { + CleanPannel, + DisableSorting, + EyeIcon, + LockIcon, +} from "../../assets/images/svgExports"; // Assuming these are your icon components + +type Side = "top" | "bottom" | "left" | "right"; + +const generateUniqueId = () => + `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; + +const DraggableWidget = ({ widget }: { widget: any }) => { + const { + attributes, + listeners, + setNodeRef, + transform, + transition, + isDragging, + } = useSortable({ id: widget.id }); + + const { selectedChartId, setSelectedChartId } = useWidgetStore(); + + const style = { + transform: transform + ? `translate3d(${transform.x}px, ${transform.y}px, 0)` + : undefined, + transition: transition || "transform 200ms ease", + }; + + const handlePointerDown = () => { + // Set selected chart when pointer down event occurs (i.e., when it's clicked, not dragged) + if (!isDragging) { + setSelectedChartId(widget); // Update selected chart in the store + } + }; + + // Log to see the selectedChartId updates + useEffect(() => { + console.log("selectedChartID: ", selectedChartId); + }, [selectedChartId]); + + return ( +
    + +
    + ); +}; + +const RealTimeVisualization = () => { + const [activeSides, setActiveSides] = useState([]); + const [panelOrder, setPanelOrder] = useState([]); + const [selectedSide, setSelectedSide] = useState(null); + const { draggedAsset, addWidget, widgets, setWidgets } = useWidgetStore(); + + // Sensors for drag-and-drop (Pointer and Keyboard) + const sensors = useSensors( + useSensor(PointerSensor), + useSensor(KeyboardSensor) + ); + + useEffect(() => {}, [widgets]); + + const toggleSide = (side: Side) => { + setActiveSides((prev) => { + const newActive = prev.includes(side) + ? prev.filter((s) => s !== side) + : [...prev, side]; + setPanelOrder(newActive); + + // Reset selectedSide if the panel is being closed + if (prev.includes(side)) { + setSelectedSide(null); // Hide extra buttons when the panel is closed + } else { + setSelectedSide(side); // Show extra buttons when the panel is opened + } + + return newActive; + }); + }; + + const getPanelStyle = (currentSide: Side) => { + const currentIndex = panelOrder.indexOf(currentSide); + const previousPanels = panelOrder.slice(0, currentIndex); + + const leftActive = previousPanels.includes("left"); + const rightActive = previousPanels.includes("right"); + const topActive = previousPanels.includes("top"); + const bottomActive = previousPanels.includes("bottom"); + + switch (currentSide) { + case "top": + case "bottom": + return { + width: `calc(100% - ${ + (leftActive ? 204 : 0) + (rightActive ? 204 : 0) + }px)`, + left: leftActive ? "204px" : "0", + right: rightActive ? "204px" : "0", + [currentSide]: "0", + height: "200px", + }; + + case "left": + case "right": + return { + height: `calc(100% - ${ + (topActive ? 204 : 0) + (bottomActive ? 204 : 0) + }px)`, + top: topActive ? "204px" : "0", + bottom: bottomActive ? "204px" : "0", + [currentSide]: "0", + width: "200px", + }; + + default: + return {}; + } + }; + + const handleDrop = (e: React.DragEvent, panel: Side) => { + e.preventDefault(); + if (draggedAsset) { + addWidget({ ...draggedAsset, id: generateUniqueId(), panel }); + } + }; + + const leftHeader = useMemo(() => ["Overview", "Widgets", "Templates"], []); + const rightHeader = useMemo(() => ["Data", "Design"], []); + + const handleDragEnd = (event: any) => { + const { active, over } = event; + + if (!over) return; + + const oldIndex = widgets.findIndex((widget) => widget.id === active.id); + const newPanel = + widgets.find((widget) => widget.id === over.id)?.panel || active.panel; + + // Ensure widgets are reordered within the same panel or moved to a new panel + if (active.panel === newPanel) { + // Reorder within the same panel + const newIndex = widgets.findIndex((widget) => widget.id === over.id); + const reorderedWidgets = arrayMove(widgets, oldIndex, newIndex); + setWidgets(reorderedWidgets); + } else { + // Move to a different panel + const updatedWidgets = widgets.map((widget) => + widget.id === active.id ? { ...widget, panel: newPanel } : widget + ); + + const widgetsInNewPanel = updatedWidgets.filter( + (w) => w.panel === newPanel + ); + const newIndex = widgetsInNewPanel.findIndex((w) => w.id === over.id); + + const reorderedWidgets = arrayMove(updatedWidgets, oldIndex, newIndex); + setWidgets(reorderedWidgets); + } + }; + + return ( + +
    + + +
    + {(["top", "right", "bottom", "left"] as Side[]).map((side) => ( +
    + {/* Side Button */} + + + {/* Extra Buttons */} +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + ))} + + {activeSides.map((side) => ( +
    handleDrop(e, side)} + onDragOver={(e) => e.preventDefault()} + > +
    + w.panel === side) + .map((w) => w.id)} + strategy={verticalListSortingStrategy} + > + {widgets + .filter((w) => w.panel === side) + .map((widget) => ( + <> + + + ))} + +
    +
    + ))} +
    + + +
    +
    + ); +}; + +export default RealTimeVisualization; diff --git a/frontend/src/pages/signin/note.txt b/frontend/src/pages/signin/note.txt new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/pages/signin/signInUp.tsx b/frontend/src/pages/signin/signInUp.tsx new file mode 100644 index 0000000..5fa2265 --- /dev/null +++ b/frontend/src/pages/signin/signInUp.tsx @@ -0,0 +1,183 @@ +import { useEffect, useState, FormEvent } from "react"; +import vectorImage from "../../assets/images/3dVector3.png"; +import { useLocation, useNavigate } from "react-router"; +import { Link } from "react-router-dom"; +import { signUp } from "../../services/factoryBuilder/signInSignUp/signUpApi"; +import { signIn } from "../../services/factoryBuilder/signInSignUp/signInApi"; +import { toast } from "react-toastify"; +import { useOrganization, useUserName } from "../../store/store"; + +interface SignInSignUpProps { + isSignIn: boolean; + setIsSignIn: (value: boolean) => void; +} + +export default function SignInSignUp({ isSignIn, setIsSignIn }: SignInSignUpProps) { + const [transition, setTransition] = useState(true); + let navigate = useNavigate(); + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const location = useLocation(); + const { userName, setUserName } = useUserName(); + const { organization, setOrganization } = useOrganization(); + + useEffect(() => { + if (location.pathname === "/Signup") { + startTransition(false, 400); + } else if (location.pathname === "/signin") { + setIsSignIn(true); + } + }, [location]); + + const handleSignIn = async (e: FormEvent) => { + e.preventDefault(); + const organization = (email.split("@")[1]).split(".")[0]; + try { + const res = await signIn(email, password, organization); + + if (res.message === "login successfull") { + toast.success('Login successfull'); + setOrganization(organization); + setUserName(res.name); + localStorage.setItem("userId", res.userId); + localStorage.setItem("email", res.email); + localStorage.setItem("userName", res.name); + if (res.isShare) { + navigate("/Project"); + } + } else if (res.message === "User Not Found!!! Kindly signup...") { + toast.error(res.message); + } + } catch (error) { } + }; + + const handleSignUp = async (e: FormEvent) => { + e.preventDefault(); + try { + const organization = (email.split("@")[1]).split(".")[0]; + const res = await signUp(userName, email, password, organization); + console.log('res: ', res); + + if (res.message === "New User created") { + toast.success('SignUp Successfull'); + startTransition(true, 400); + } + if (res.message === "User already exists") { + toast.success("User already exists"); + } + } catch (error) { } + }; + + function startTransition(value: boolean, duration: number) { + setTransition(!transition); + setTimeout(() => { + setIsSignIn(value); + if (location.pathname === "/signup") { + navigate("/"); + } else { + navigate("/signup"); + } + }, duration); + } + + return ( +
    +
    +
    +
    + {isSignIn ? "Welcome Back!" : "Hello Friend!"} +
    +
    + Embedded at its core are predictive analytics and real-time monitoring, curbing unexpected downtime and enabling seamless integration with existing systems. Experience a revolutionary approach to resource management, enhanced productivity, and cost reduction. +
    + cover-image +
    +
    +
    + {isSignIn ? "Log in to your Account" : "Create Account"} +
    +
    +
    { + isSignIn ? handleSignIn(event) : handleSignUp(event); + }} + > + {!isSignIn && ( +
    +
    User name
    + setUserName(e.target.value)} + required + /> +
    + )} +
    +
    Email
    + setEmail(e.target.value)} + required + /> +
    +
    +
    Password
    + setPassword(e.target.value)} + required + /> +
    +
    + {isSignIn ? ( +
    Forget Password!
    + ) : ( + "" + )} +
    +
    + +
    +
    +
    +
    + {isSignIn ? ( +
    +
    Don't have an account?
    +
    { + startTransition(false, 400); + }} + > + Sign up! +
    +
    + ) : ( +
    +
    Already have an account?
    +
    { + startTransition(true, 400); + }} + > + Login! +
    +
    + )} +
    +
    +
    +
    + ); +} diff --git a/frontend/src/pages/signup/note.txt b/frontend/src/pages/signup/note.txt new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/reactAppEnv.d.ts b/frontend/src/reactAppEnv.d.ts new file mode 100644 index 0000000..6431bc5 --- /dev/null +++ b/frontend/src/reactAppEnv.d.ts @@ -0,0 +1 @@ +/// diff --git a/frontend/src/reportWebVitals.ts b/frontend/src/reportWebVitals.ts new file mode 100644 index 0000000..49a2a16 --- /dev/null +++ b/frontend/src/reportWebVitals.ts @@ -0,0 +1,15 @@ +import { ReportHandler } from 'web-vitals'; + +const reportWebVitals = (onPerfEntry?: ReportHandler) => { + if (onPerfEntry && onPerfEntry instanceof Function) { + import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { + getCLS(onPerfEntry); + getFID(onPerfEntry); + getFCP(onPerfEntry); + getLCP(onPerfEntry); + getTTFB(onPerfEntry); + }); + } +}; + +export default reportWebVitals; diff --git a/frontend/src/services/factoryBuilder/assest/assets/getAssetImages.ts b/frontend/src/services/factoryBuilder/assest/assets/getAssetImages.ts new file mode 100644 index 0000000..9d41601 --- /dev/null +++ b/frontend/src/services/factoryBuilder/assest/assets/getAssetImages.ts @@ -0,0 +1,23 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`; + +export const getAssetImages = async (cursor?: string) => { + try { + const response = await fetch( + `${url_Backend_dwinzo}/api/v3/AssetDatas?limit=10${cursor ? `&cursor=${cursor}` : ""}`, + { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + } + ); + + if (!response.ok) { + throw new Error("Failed to fetch assets"); + } + + return await response.json(); + } catch (error: any) { + throw new Error(error.message); + } +}; diff --git a/frontend/src/services/factoryBuilder/assest/assets/getAssetModel.ts b/frontend/src/services/factoryBuilder/assest/assets/getAssetModel.ts new file mode 100644 index 0000000..cf1ed5a --- /dev/null +++ b/frontend/src/services/factoryBuilder/assest/assets/getAssetModel.ts @@ -0,0 +1,25 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`; + +export const getAssetModel = async (modelId: string) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/v1/AssetFile/${modelId}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }); + + if (!response.ok) { + throw new Error("Failed to fetch model"); + } + + const result = await response.json(); + return result; + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/assest/floorAsset/deleteFloorItemApi.ts b/frontend/src/services/factoryBuilder/assest/floorAsset/deleteFloorItemApi.ts new file mode 100644 index 0000000..ecd7a54 --- /dev/null +++ b/frontend/src/services/factoryBuilder/assest/floorAsset/deleteFloorItemApi.ts @@ -0,0 +1,26 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export const deleteFloorItem = async (organization: string, modeluuid: string, modelname: string) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/v1/deletefloorItem`, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ organization, modeluuid, modelname }), + }); + + if (!response.ok) { + throw new Error("Failed to delete Floor Item"); + } + + const result = await response.json(); + return result; + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/assest/floorAsset/getFloorItemsApi.ts b/frontend/src/services/factoryBuilder/assest/floorAsset/getFloorItemsApi.ts new file mode 100644 index 0000000..ad315e7 --- /dev/null +++ b/frontend/src/services/factoryBuilder/assest/floorAsset/getFloorItemsApi.ts @@ -0,0 +1,25 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export const getFloorItems = async (organization: string) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/v1/findfloorItems/${organization}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }); + + if (!response.ok) { + throw new Error("Failed to get Floor Items"); + } + + const result = await response.json(); + return result; + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/assest/floorAsset/setFloorItemApi.ts b/frontend/src/services/factoryBuilder/assest/floorAsset/setFloorItemApi.ts new file mode 100644 index 0000000..a4fe765 --- /dev/null +++ b/frontend/src/services/factoryBuilder/assest/floorAsset/setFloorItemApi.ts @@ -0,0 +1,26 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export const setFloorItemApi = async (organization: string, modeluuid: string, modelname: string, position: Object, rotation: Object, modelfileID: string, isLocked: boolean, isVisible: boolean) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/v1/setFloorItems`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ organization, modeluuid, modelname, position, rotation, modelfileID, isLocked, isVisible }), + }); + + if (!response.ok) { + throw new Error("Failed to set or update Floor Item"); + } + + const result = await response.json(); + return result; + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/assest/wallAsset/deleteWallItemApi.ts b/frontend/src/services/factoryBuilder/assest/wallAsset/deleteWallItemApi.ts new file mode 100644 index 0000000..5dda37c --- /dev/null +++ b/frontend/src/services/factoryBuilder/assest/wallAsset/deleteWallItemApi.ts @@ -0,0 +1,26 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export const deleteWallItem = async (organization: string, modeluuid: string, modelname: string) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/v1/deleteWallItem`, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ organization, modeluuid, modelname }), + }); + + if (!response.ok) { + throw new Error("Failed to delete Wall Item"); + } + + const result = await response.json(); + return result; + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/assest/wallAsset/getWallItemsApi.ts b/frontend/src/services/factoryBuilder/assest/wallAsset/getWallItemsApi.ts new file mode 100644 index 0000000..eb0a232 --- /dev/null +++ b/frontend/src/services/factoryBuilder/assest/wallAsset/getWallItemsApi.ts @@ -0,0 +1,25 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export const getWallItems = async (organization: string) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/v1/findWallItems/${organization}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }); + + if (!response.ok) { + throw new Error("Failed to get Wall Items"); + } + + const result = await response.json(); + return result; + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/assest/wallAsset/setWallItemApi.ts b/frontend/src/services/factoryBuilder/assest/wallAsset/setWallItemApi.ts new file mode 100644 index 0000000..e51297b --- /dev/null +++ b/frontend/src/services/factoryBuilder/assest/wallAsset/setWallItemApi.ts @@ -0,0 +1,36 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export const setWallItem = async ( + organization: string, + modeluuid: string, + modelname: string, + type: string, + csgposition: Object, + csgscale: Object, + position: Object, + quaternion: Object, + scale: Object +) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/v1/setWallItems`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ organization, modeluuid, modelname, position, type, csgposition, csgscale, quaternion, scale }), + }); + + if (!response.ok) { + throw new Error("Failed to set or update Wall Item"); + } + + const result = await response.json(); + return result; + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/camera/getCameraApi.ts b/frontend/src/services/factoryBuilder/camera/getCameraApi.ts new file mode 100644 index 0000000..e8d84d9 --- /dev/null +++ b/frontend/src/services/factoryBuilder/camera/getCameraApi.ts @@ -0,0 +1,32 @@ +import { setCamera } from './setCameraApi'; +import * as THREE from 'three'; + +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export const getCamera = async (organization: string, userId: string) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/v1/getCamera/${organization}/${userId}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }); + + if (!response.ok) { + throw new Error("Failed to get Camera position and target"); + } + + const result = await response.json(); + if (result === "user not found") { + return null; + } else { + return result; + } + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/camera/setCameraApi.ts b/frontend/src/services/factoryBuilder/camera/setCameraApi.ts new file mode 100644 index 0000000..46d30e3 --- /dev/null +++ b/frontend/src/services/factoryBuilder/camera/setCameraApi.ts @@ -0,0 +1,26 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export const setCamera = async (organization: string, userId: string, position: Object, target: Object, rotation: Object) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/v1/setCamera`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ organization, userId, position, target, rotation }), + }); + + if (!response.ok) { + throw new Error("Failed to set Camera Position and Target"); + } + + const result = await response.json(); + return result; + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/collab/getActiveUsers.ts b/frontend/src/services/factoryBuilder/collab/getActiveUsers.ts new file mode 100644 index 0000000..30242b6 --- /dev/null +++ b/frontend/src/services/factoryBuilder/collab/getActiveUsers.ts @@ -0,0 +1,32 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export default async function getActiveUsersData(organization: string) { + const apiUrl = `${url_Backend_dwinzo}/api/v1/activeCameras/${organization}`; + + try { + const response = await fetch(apiUrl, { + method: "GET", + headers: { + "Content-Type": "application/json" + } + }); + + if (!response.ok) { + throw new Error(`Error: ${response.status} - ${response.statusText}`); + } + + + if (!response.ok) { + throw new Error("Failed to get active cameras "); + } + + const result = await response.json(); + return result; + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/collab/getUsersApi.ts b/frontend/src/services/factoryBuilder/collab/getUsersApi.ts new file mode 100644 index 0000000..808eb76 --- /dev/null +++ b/frontend/src/services/factoryBuilder/collab/getUsersApi.ts @@ -0,0 +1,32 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export default async function fetchShareUsers(organization: string) { + const apiUrl = `${url_Backend_dwinzo}/api/v1/findshareUsers?organization=${organization}`; + + try { + const response = await fetch(apiUrl, { + method: "GET", + headers: { + "Content-Type": "application/json" + } + }); + + if (!response.ok) { + throw new Error(`Error: ${response.status} - ${response.statusText}`); + } + + + if (!response.ok) { + throw new Error("Failed to get users "); + } + + const result = await response.json(); + return result; + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/collab/giveCollabAccess.ts b/frontend/src/services/factoryBuilder/collab/giveCollabAccess.ts new file mode 100644 index 0000000..b70b4f7 --- /dev/null +++ b/frontend/src/services/factoryBuilder/collab/giveCollabAccess.ts @@ -0,0 +1,26 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export default async function giveCollabAccess(email: string, isShare: boolean, organization: string) { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/v1/shareUser`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ email, isShare, organization }), + }); + + if (!response.ok) { + throw new Error("Failed to set Camera Position and Target"); + } + + const result = await response.json(); + return result; + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/environment/findEnvironment.ts b/frontend/src/services/factoryBuilder/environment/findEnvironment.ts new file mode 100644 index 0000000..ff81b07 --- /dev/null +++ b/frontend/src/services/factoryBuilder/environment/findEnvironment.ts @@ -0,0 +1,32 @@ +import { setEnvironment } from './setEnvironment'; + +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export const findEnvironment = async (organization: string, userId: string) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/v1/findEnvironments/${organization}/${userId}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }); + + if (!response.ok) { + throw new Error("Failed to get wall and roof visibility"); + } + + const result = await response.json(); + if (result === "user not found") { + const userpos = setEnvironment(organization, userId, false, false, false); + return userpos; + } else { + return result; + } + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/environment/setEnvironment.ts b/frontend/src/services/factoryBuilder/environment/setEnvironment.ts new file mode 100644 index 0000000..072b7bb --- /dev/null +++ b/frontend/src/services/factoryBuilder/environment/setEnvironment.ts @@ -0,0 +1,26 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export const setEnvironment = async (organization: string, userId: string, wallVisibility: Boolean, roofVisibility: Boolean, shadowVisibility: Boolean) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/v1/setEvironments`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ organization, userId, wallVisibility, roofVisibility, shadowVisibility }), + }); + + if (!response.ok) { + throw new Error("Failed to set wall and roof visibility"); + } + + const result = await response.json(); + return result; + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/lines/deleteLayerApi.ts b/frontend/src/services/factoryBuilder/lines/deleteLayerApi.ts new file mode 100644 index 0000000..54160c8 --- /dev/null +++ b/frontend/src/services/factoryBuilder/lines/deleteLayerApi.ts @@ -0,0 +1,26 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export const deleteLayer = async (organization: string, layer: number) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/v1/deleteLayer`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ organization, layer }), + }); + + if (!response.ok) { + throw new Error("Failed to delete line"); + } + + const result = await response.json(); + return result; + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/lines/deleteLineApi.ts b/frontend/src/services/factoryBuilder/lines/deleteLineApi.ts new file mode 100644 index 0000000..64a76c4 --- /dev/null +++ b/frontend/src/services/factoryBuilder/lines/deleteLineApi.ts @@ -0,0 +1,26 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export const deleteLineApi = async (organization: string, line: Object) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/v1/deleteLine`, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ organization, line }), + }); + + if (!response.ok) { + throw new Error("Failed to delete line"); + } + + const result = await response.json(); + return result; + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/lines/deletePointApi.ts b/frontend/src/services/factoryBuilder/lines/deletePointApi.ts new file mode 100644 index 0000000..60a6fd4 --- /dev/null +++ b/frontend/src/services/factoryBuilder/lines/deletePointApi.ts @@ -0,0 +1,26 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export const deletePointApi = async (organization: string, uuid: string) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/v1/deletePoint`, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ organization, uuid }), + }); + + if (!response.ok) { + throw new Error("Failed to delete point"); + } + + const result = await response.json(); + return result; + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/lines/getLinesApi.ts b/frontend/src/services/factoryBuilder/lines/getLinesApi.ts new file mode 100644 index 0000000..00c86a9 --- /dev/null +++ b/frontend/src/services/factoryBuilder/lines/getLinesApi.ts @@ -0,0 +1,25 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export const getLines = async (organization: string) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/v1/findLines/${organization}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }); + + if (!response.ok) { + throw new Error("Failed to get Lines"); + } + + const result = await response.json(); + return result; + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/lines/setLineApi.ts b/frontend/src/services/factoryBuilder/lines/setLineApi.ts new file mode 100644 index 0000000..269c26d --- /dev/null +++ b/frontend/src/services/factoryBuilder/lines/setLineApi.ts @@ -0,0 +1,26 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export const setLine = async (organization: string, layer: number, line: Object, type: string) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/v1/setLine`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ organization, layer, line, type }), + }); + + if (!response.ok) { + throw new Error("Failed to set line"); + } + + const result = await response.json(); + return result; + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/lines/updatePointApi.ts b/frontend/src/services/factoryBuilder/lines/updatePointApi.ts new file mode 100644 index 0000000..8e4a93a --- /dev/null +++ b/frontend/src/services/factoryBuilder/lines/updatePointApi.ts @@ -0,0 +1,26 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export const updatePoint = async (organization: string, position: Object, uuid: string) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/v1/updatePoint`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ organization, position, uuid }), + }); + + if (!response.ok) { + throw new Error("Failed to update point"); + } + + const result = await response.json(); + return result; + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/mqtt/mqttEvents.ts b/frontend/src/services/factoryBuilder/mqtt/mqttEvents.ts new file mode 100644 index 0000000..fc009be --- /dev/null +++ b/frontend/src/services/factoryBuilder/mqtt/mqttEvents.ts @@ -0,0 +1,48 @@ +import React, { useEffect } from "react"; +import mqtt from "mqtt"; +import { useDrieUIValue } from "../../../store/store"; + +const MqttEvents = () => { + const { setTouch, setTemperature, setHumidity } = useDrieUIValue(); + useEffect(() => { + + const client = mqtt.connect("ws://192.168.0.192:1884", { + username: "gabby", + password: "gabby" + }); + + client.subscribe("touch"); + client.subscribe("temperature"); + client.subscribe("humidity"); + + const handleMessage = (topic: string, message: any) => { + const value = message.toString(); + + if (topic === "touch") { + setTouch(value); + } else if (topic === "temperature") { + setTemperature(parseFloat(value)); + } else if (topic === "humidity") { + setHumidity(parseFloat(value)); + } + }; + + client.on("message", handleMessage); + + client.on("error", (err) => { + console.error("MQTT Connection Error:", err); + }); + + client.on("close", () => { + console.log("MQTT Connection Closed"); + }); + + return () => { + client.end(); + }; + }, [setTouch, setTemperature, setHumidity]); + + return null; +}; + +export default MqttEvents; diff --git a/frontend/src/services/factoryBuilder/signInSignUp/signInApi.ts b/frontend/src/services/factoryBuilder/signInSignUp/signInApi.ts new file mode 100644 index 0000000..be608c0 --- /dev/null +++ b/frontend/src/services/factoryBuilder/signInSignUp/signInApi.ts @@ -0,0 +1,22 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export const signIn = async (email: string, password: Object, organization: Object) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/v1/login`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ email, password, organization }), + }); + + const result = await response.json(); + return result; + } catch (error) { + if (error instanceof Error) { + return { error: error.message }; + } else { + return { error: "An unknown error occurred" }; + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/signInSignUp/signUpApi.ts b/frontend/src/services/factoryBuilder/signInSignUp/signUpApi.ts new file mode 100644 index 0000000..87ded2b --- /dev/null +++ b/frontend/src/services/factoryBuilder/signInSignUp/signUpApi.ts @@ -0,0 +1,26 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export const signUp = async (userName: string, email: string, password: Object, organization: Object) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/v1/signup`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ userName, email, password, organization }), + }); + + if (!response.ok) { + throw new Error("Failed to signUp"); + } + + const result = await response.json(); + return result; + } catch (error) { + if (error instanceof Error) { + throw new Error(error.message); + } else { + throw new Error("An unknown error occurred"); + } + } +}; \ No newline at end of file diff --git a/frontend/src/services/factoryBuilder/webWorkers/assetManagerWorker.js b/frontend/src/services/factoryBuilder/webWorkers/assetManagerWorker.js new file mode 100644 index 0000000..db17487 --- /dev/null +++ b/frontend/src/services/factoryBuilder/webWorkers/assetManagerWorker.js @@ -0,0 +1,51 @@ +import * as THREE from 'three'; +import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; +import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'; + +const loader = new GLTFLoader(); +const dracoLoader = new DRACOLoader(); +dracoLoader.setDecoderPath('https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/'); +loader.setDRACOLoader(dracoLoader); + +onmessage = (event) => { + const { floorItems, cameraPosition, uuids, renderDistance } = event.data; + if (!floorItems) return + + const toAdd = []; + const toRemove = []; + + const cameraPos = new THREE.Vector3(cameraPosition.x, cameraPosition.y, cameraPosition.z); + + // Check for items to be added + floorItems.forEach((item) => { + const itemPosition = new THREE.Vector3(...item.position); + const distance = cameraPos.distanceTo(itemPosition); + + if (distance <= renderDistance && !uuids.includes(item.modeluuid)) { + toAdd.push(item); + } + }); + + // Sort the toAdd array based on distance (closest first) + toAdd.sort((a, b) => { + const aDistance = cameraPos.distanceTo(new THREE.Vector3(...a.position)); + const bDistance = cameraPos.distanceTo(new THREE.Vector3(...b.position)); + return aDistance - bDistance; + }); + + // Check for items to be removed + uuids.forEach((uuid) => { + const floorItem = floorItems.find((item) => item.modeluuid === uuid); + if (floorItem) { + const itemPosition = new THREE.Vector3(...floorItem.position); + const distance = cameraPos.distanceTo(itemPosition); + + if (distance > renderDistance) { + toRemove.push(uuid); + } + } + }); + + // Send the result back to the main thread + postMessage({ toAdd, toRemove }); +}; diff --git a/frontend/src/services/factoryBuilder/webWorkers/gltfLoaderWorker.js b/frontend/src/services/factoryBuilder/webWorkers/gltfLoaderWorker.js new file mode 100644 index 0000000..a051538 --- /dev/null +++ b/frontend/src/services/factoryBuilder/webWorkers/gltfLoaderWorker.js @@ -0,0 +1,38 @@ +import * as THREE from 'three'; +import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; +import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'; +import { retrieveGLTF, storeGLTF } from '../../../components/scene/indexDB/idbUtils'; + +const loader = new GLTFLoader(); +const dracoLoader = new DRACOLoader(); +dracoLoader.setDecoderPath('https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/'); +loader.setDRACOLoader(dracoLoader); +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`; + +onmessage = async (event) => { + const { floorItems } = event.data; + + const uniqueItems = floorItems.filter((item, index, self) => + index === self.findIndex((t) => t.modelfileID === item.modelfileID) + ); + + for (const item of uniqueItems) { + const modelID = item.modelfileID; + const indexedDBModel = await retrieveGLTF(modelID); + + let modelBlob; + if (indexedDBModel) { + modelBlob = indexedDBModel; + const message = "gltfLoaded"; + postMessage({ message, modelID, modelBlob }); + } else { + const modelUrl = `${url_Backend_dwinzo}/api/v1/AssetFile/${modelID}`; + const modelBlob = await fetch(modelUrl).then((res) => res.blob()); + await storeGLTF(modelID, modelBlob); + const message = "gltfLoaded"; + postMessage({ message, modelID, modelBlob }); + } + } + + postMessage({ message: 'done' }) +}; diff --git a/frontend/src/services/factoryBuilder/webWorkers/shadowWorker.js b/frontend/src/services/factoryBuilder/webWorkers/shadowWorker.js new file mode 100644 index 0000000..67bd52a --- /dev/null +++ b/frontend/src/services/factoryBuilder/webWorkers/shadowWorker.js @@ -0,0 +1,11 @@ +import * as THREE from 'three'; + +onmessage = (event) => { + const { controlsTarget, sunPosition, offsetDistance } = event.data; + + const lightPosition = new THREE.Vector3() + .copy(controlsTarget) + .addScaledVector(new THREE.Vector3().copy(sunPosition).normalize(), offsetDistance); + + postMessage({ lightPosition, controlsTarget }); +}; \ No newline at end of file diff --git a/frontend/src/services/note.txt b/frontend/src/services/note.txt new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/setupTests.ts b/frontend/src/setupTests.ts new file mode 100644 index 0000000..8f2609b --- /dev/null +++ b/frontend/src/setupTests.ts @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom'; diff --git a/frontend/src/store/store.ts b/frontend/src/store/store.ts new file mode 100644 index 0000000..a0c5313 --- /dev/null +++ b/frontend/src/store/store.ts @@ -0,0 +1,330 @@ +import { create } from "zustand"; +import { io } from "socket.io-client"; + +export const useSocketStore = create((set: any, get: any) => ({ + socket: null, + initializeSocket: (email: any) => { + const existingSocket = get().socket; + if (existingSocket) { + return; + } + + const socket = io( + `http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/`, + { + reconnection: false, + auth: { email }, + } + ); + + set({ socket }); + }, + disconnectSocket: () => { + set((state: any) => { + state.socket?.disconnect(); + return { socket: null }; + }); + }, +})); + +export const useOrganization = create((set: any) => ({ + organization: "", + setOrganization: (x: any) => set(() => ({ organization: x })), +})); + +export const useToggleView = create((set: any) => ({ + toggleView: false, + setToggleView: (x: any) => set(() => ({ toggleView: x })), +})); + +export const useUpdateScene = create((set: any) => ({ + updateScene: false, + setUpdateScene: (x: any) => set(() => ({ updateScene: x })), +})); + +export const useWalls = create((set: any) => ({ + walls: [], + setWalls: (x: any) => set(() => ({ walls: x })), +})); + +export const useSelectedItem = create((set: any) => ({ + selectedItem: { name: "", id: "" }, + setSelectedItem: (x: any) => set(() => ({ selectedItem: x })), +})); + +export const useSelectedAssets = create((set: any) => ({ + selectedAssets: [], + setSelectedAssets: (x: any) => set(() => ({ selectedAssets: x })), +})); + +export const useLayers = create((set: any) => ({ + Layers: 1, + setLayers: (x: any) => set(() => ({ Layers: x })), +})); + +export const useCamPosition = create((set: any) => ({ + camPosition: { x: undefined, y: undefined, z: undefined }, + setCamPosition: (newCamPosition: any) => set({ camPosition: newCamPosition }), +})); + +export const useMenuVisible = create((set: any) => ({ + menuVisible: false, + setMenuVisible: (x: any) => set(() => ({ menuVisible: x })), +})); + +export const useDeleteModels = create((set: any) => ({ + deleteModels: false, + setDeleteModels: (x: any) => set(() => ({ deleteModels: x })), +})); + +export const useToolMode = create((set: any) => ({ + toolMode: null, + setToolMode: (x: any) => set(() => ({ toolMode: x })), +})); + +export const useNewLines = create((set: any) => ({ + newLines: [], + setNewLines: (x: any) => set(() => ({ newLines: x })), +})); + +export const useDeletedLines = create((set: any) => ({ + deletedLines: [], + setDeletedLines: (x: any) => set(() => ({ deletedLines: x })), +})); + +export const useMovePoint = create((set: any) => ({ + movePoint: false, + setMovePoint: (x: any) => set(() => ({ movePoint: x })), +})); + +export const useTransformMode = create((set: any) => ({ + transformMode: null, + setTransformMode: (x: any) => set(() => ({ transformMode: x })), +})); + +export const useDeletePointOrLine = create((set: any) => ({ + deletePointOrLine: false, + setDeletePointOrLine: (x: any) => set(() => ({ deletePointOrLine: x })), +})); + +export const useFloorItems = create((set: any) => ({ + floorItems: null, + setFloorItems: (callback: any) => + set((state: any) => ({ + floorItems: + typeof callback === "function" ? callback(state.floorItems) : callback, + })), +})); + +export const useWallItems = create((set: any) => ({ + wallItems: [], + setWallItems: (callback: any) => + set((state: any) => ({ + wallItems: + typeof callback === "function" ? callback(state.wallItems) : callback, + })), +})); + +export const useSelectedWallItem = create((set: any) => ({ + selectedWallItem: null, + setSelectedWallItem: (x: any) => set(() => ({ selectedWallItem: x })), +})); + +export const useselectedFloorItem = create((set: any) => ({ + selectedFloorItem: null, + setselectedFloorItem: (x: any) => set(() => ({ selectedFloorItem: x })), +})); + +export const useDeletableFloorItem = create((set: any) => ({ + deletableFloorItem: null, + setDeletableFloorItem: (x: any) => set(() => ({ deletableFloorItem: x })), +})); + +export const useSetScale = create((set: any) => ({ + scale: null, + setScale: (x: any) => set(() => ({ scale: x })), +})); + +export const useRoofVisibility = create((set: any) => ({ + roofVisibility: false, + setRoofVisibility: (x: any) => set(() => ({ roofVisibility: x })), +})); + +export const useWallVisibility = create((set: any) => ({ + wallVisibility: false, + setWallVisibility: (x: any) => set(() => ({ wallVisibility: x })), +})); + +export const useShadows = create((set: any) => ({ + shadows: false, + setShadows: (x: any) => set(() => ({ shadows: x })), +})); + +export const useSunPosition = create((set: any) => ({ + sunPosition: { x: undefined, y: undefined, z: undefined }, + setSunPosition: (newSuntPosition: any) => + set({ sunPosition: newSuntPosition }), +})); + +export const useRemoveLayer = create((set: any) => ({ + removeLayer: false, + setRemoveLayer: (x: any) => set(() => ({ removeLayer: x })), +})); + +export const useRemovedLayer = create((set: any) => ({ + removedLayer: null, + setRemovedLayer: (x: any) => set(() => ({ removedLayer: x })), +})); + +export const useActiveLayer = create((set: any) => ({ + activeLayer: 1, + setActiveLayer: (x: any) => set({ activeLayer: x }), +})); + +export const useResetCamera = create((set: any) => ({ + resetCamera: false, + setResetCamera: (x: any) => set({ resetCamera: x }), +})); + +export const useAddAction = create((set: any) => ({ + addAction: null, + setAddAction: (x: any) => set({ addAction: x }), +})); + +export const useActiveTool = create((set: any) => ({ + activeTool: "Cursor", + setActiveTool: (x: any) => set({ activeTool: x }), +})); + +export const use2DUndoRedo = create((set: any) => ({ + is2DUndoRedo: null, + set2DUndoRedo: (x: any) => set({ is2DUndoRedo: x }), +})); + +export const useElevation = create((set: any) => ({ + elevation: 45, + setElevation: (x: any) => set({ elevation: x }), +})); + +export const useAzimuth = create((set: any) => ({ + azimuth: -160, + setAzimuth: (x: any) => set({ azimuth: x }), +})); + +export const useRenderDistance = create((set: any) => ({ + renderDistance: 50, + setRenderDistance: (x: any) => set({ renderDistance: x }), +})); + +export const useCamMode = create((set: any) => ({ + camMode: "ThirdPerson", + setCamMode: (x: any) => set({ camMode: x }), +})); + +export const useUserName = create((set: any) => ({ + userName: "", + setUserName: (x: any) => set({ userName: x }), +})); + +export const useObjectPosition = create((set: any) => ({ + objectPosition: { x: undefined, y: undefined, z: undefined }, + setObjectPosition: (newObjectPosition: any) => + set({ objectPosition: newObjectPosition }), +})); + +export const useObjectScale = create((set: any) => ({ + objectScale: { x: undefined, y: undefined, z: undefined }, + setObjectScale: (newObjectScale: any) => set({ objectScale: newObjectScale }), +})); + +export const useObjectRotation = create((set: any) => ({ + objectRotation: { x: undefined, y: undefined, z: undefined }, + setObjectRotation: (newObjectRotation: any) => + set({ objectRotation: newObjectRotation }), +})); + +export const useDrieTemp = create((set: any) => ({ + drieTemp: undefined, + setDrieTemp: (x: any) => set({ drieTemp: x }), +})); + +export const useActiveUsers = create((set: any) => ({ + activeUsers: [], + setActiveUsers: (x: any) => set({ activeUsers: x }), +})); + +export const useDrieUIValue = create((set: any) => ({ + drieUIValue: { touch: null, temperature: null, humidity: null }, + + setDrieUIValue: (x: any) => + set((state: any) => ({ drieUIValue: { ...state.drieUIValue, ...x } })), + + setTouch: (value: any) => + set((state: any) => ({ + drieUIValue: { ...state.drieUIValue, touch: value }, + })), + setTemperature: (value: any) => + set((state: any) => ({ + drieUIValue: { ...state.drieUIValue, temperature: value }, + })), + setHumidity: (value: any) => + set((state: any) => ({ + drieUIValue: { ...state.drieUIValue, humidity: value }, + })), +})); + +type Side = "top" | "bottom" | "left" | "right"; + +// Define Widget interface +interface Widget { + id: string; + type: any; + panel: Side; + title: string; // Ensure title is a string + fontFamily?: string; + fontSize?: string; + fontWeight?: string; +} + +// Store interface +interface WidgetStore { + draggedAsset: { type: any; id: string; title: string } | null; + widgets: Widget[]; + setDraggedAsset: ( + asset: { type: any; id: string; title: string } | null + ) => void; + addWidget: (widget: Widget) => void; + setWidgets: (widgets: Widget[]) => void; + selectedChartId: Widget | null; // Change this to store an object of type Widget + setSelectedChartId: (widget: Widget | { + "type": "line", + "id": "1741781992712-ecvq5t61y", + "title": "Widget 2", + "panel": "left", + "fontWeight": "Light", + "fontSize": "12px", + "fontFamily": "Sans-serif" +}) => void; // Update to accept a Widget object +} + +// Create the store with Zustand +export const useWidgetStore = create((set) => ({ + draggedAsset: null, + widgets: [], + setDraggedAsset: (asset) => set({ draggedAsset: asset }), + addWidget: (widget) => + set((state) => ({ widgets: [...state.widgets, widget] })), + setWidgets: (widgets) => set({ widgets }), + selectedChartId: null, + setSelectedChartId: (widget) => set({ selectedChartId: widget }), +})); + +interface ThemeState { + themeColor: string[]; // This should be an array of strings + setThemeColor: (colors: string[]) => void; // This function will accept an array of strings +} + +export const useThemeStore = create((set) => ({ + themeColor: ["#5c87df", "#EEEEFE", "#969BA7"], + setThemeColor: (colors) => set({ themeColor: colors }), +})); diff --git a/frontend/src/tests/e2e/cypress.config.js b/frontend/src/tests/e2e/cypress.config.js new file mode 100644 index 0000000..4536527 --- /dev/null +++ b/frontend/src/tests/e2e/cypress.config.js @@ -0,0 +1,12 @@ +const { defineConfig } = require("cypress"); + +module.exports = defineConfig({ + e2e: { + setupNodeEvents(on, config) { + // implement node event listeners here + }, + baseUrl: "http://localhost:3000", + specPattern: "src/tests/e2e/integration/**/*.cy.{js,jsx,ts,tsx}", + supportFile: "src/tests/e2e/support/index.ts", + }, +}); diff --git a/frontend/src/tests/unit/jest.config.js b/frontend/src/tests/unit/jest.config.js new file mode 100644 index 0000000..52a7028 --- /dev/null +++ b/frontend/src/tests/unit/jest.config.js @@ -0,0 +1,12 @@ +module.exports = { + preset: "ts-jest", + testEnvironment: "jsdom", + setupFilesAfterEnv: ["/src/tests/unit/setupTests.ts"], + moduleNameMapper: { + "\\.(css|scss)$": "identity-obj-proxy", + }, + transform: { + "^.+\\.tsx?$": "ts-jest", + }, + testMatch: ["/src/**/*.{test,spec}.{ts,tsx}"], +}; diff --git a/frontend/src/tests/unit/setupTests.ts b/frontend/src/tests/unit/setupTests.ts new file mode 100644 index 0000000..a678518 --- /dev/null +++ b/frontend/src/tests/unit/setupTests.ts @@ -0,0 +1 @@ +import '@testing-library/jest-dom/extend-expect'; \ No newline at end of file diff --git a/frontend/src/types/declarations.d.ts b/frontend/src/types/declarations.d.ts new file mode 100644 index 0000000..00594f0 --- /dev/null +++ b/frontend/src/types/declarations.d.ts @@ -0,0 +1,8 @@ +declare module '*.png'; +declare module '*.svg'; +declare module '*.hdr'; +declare module '*.css'; +declare module '*.scss'; + +declare module '*.glb'; +declare module '*.gltf'; \ No newline at end of file diff --git a/frontend/src/utils/contextmenuHandler.ts b/frontend/src/utils/contextmenuHandler.ts new file mode 100644 index 0000000..1f71466 --- /dev/null +++ b/frontend/src/utils/contextmenuHandler.ts @@ -0,0 +1,137 @@ +import React, { useState } from "react"; + +interface HandleDivProps { + switchesRef: React.RefObject; + setMenuLeftPosition: React.Dispatch>; + setMenuTopPosition: React.Dispatch>; + setMenuVisible: React.Dispatch>; +} +// The functional component that handles right-click (contextmenu) events +export default function ContextMenuHandler({ + switchesRef, + setMenuLeftPosition, + setMenuTopPosition, + setMenuVisible, +}: HandleDivProps) { + const [width, setWidth] = useState(0); + const [height, setHeight] = useState(0); + + // Function to handle the contextmenu event when a right-click happens + const handleClick = (event: MouseEvent) => { + event.preventDefault(); + const targets = event.target as HTMLElement; + const isInsideSwitches = switchesRef.current?.contains( + targets as Node + ); + const rect = switchesRef.current?.getBoundingClientRect(); + if (!rect) return; + + const totalHeight = rect.height + rect.top; + + const totalWidth = rect.width + rect.left; + + // Calculate the new position for the context menu + if (isInsideSwitches) { + const yPosition = event.clientY; + const xPosition = event.clientX; + //for top contextmenu handling + + if ( + totalHeight - yPosition > 20 && + totalHeight - yPosition < 260 + ) { + const minTop = yPosition - 110; + setMenuTopPosition(minTop); + } else if ( + totalHeight - yPosition >= 260 && + yPosition > height - 73 + ) { + const minTop = yPosition + 115; + setMenuTopPosition(minTop); + } + + // for top contextmenu handling + if ( + totalWidth - xPosition > 500 && + totalWidth - xPosition < 900 + ) { + const minLeft = xPosition + 80; + setMenuLeftPosition(minLeft); + } else if ( + totalWidth - xPosition > 10 && + totalWidth - xPosition > 150 + ) { + const minLeft = xPosition + 80; + setMenuLeftPosition(minLeft); + } else { + const minLeft = xPosition - 80; + setMenuLeftPosition(minLeft); + } + // setMenuVisible(true); + } else { + setMenuVisible(false); + } + }; + React.useEffect(() => { + const element = switchesRef.current; + + // Create a resize observer + const resizeObserver = new ResizeObserver((entries) => { + if (entries.length > 0) { + // Update the width state with the new width of the element + const { width, height } = entries[0].contentRect; + setWidth(width); + setHeight(height); + } + }); + + // Start observing the element's width changes + if (element) { + resizeObserver.observe(element); + } + + // Cleanup observer on component unmount + return () => { + if (element) { + resizeObserver.unobserve(element); + + } + }; + }, [height, width]); + + React.useEffect(() => { + let drag = false; + let isRightMouseDown = false; + + const handleDown = (event: MouseEvent) => { + if (event.button === 2) { + isRightMouseDown = true; + drag = false; + } + } + + const handleUp = (event: MouseEvent) => { + if (event.button === 2) { + isRightMouseDown = false; + if (!drag) { + handleClick(event); + } + }; + } + + const handleMove = (event: MouseEvent) => { + if (isRightMouseDown) { drag = true; }; + } + + document.addEventListener("mousedown", handleDown); + document.addEventListener("mousemove", handleMove); + document.addEventListener("mouseup", handleUp); + + return () => { + document.removeEventListener("mousedown", handleDown); + document.removeEventListener("mousemove", handleMove); + document.removeEventListener("mouseup", handleUp); + }; + }, []); + return null; +} diff --git a/frontend/src/utils/outerClick.ts b/frontend/src/utils/outerClick.ts new file mode 100644 index 0000000..c5a6f74 --- /dev/null +++ b/frontend/src/utils/outerClick.ts @@ -0,0 +1,29 @@ +import React from "react"; + +interface OuterClickProps { + contextClassName: string; + setMenuVisible: React.Dispatch>; +} + +export default function OuterClick({ + contextClassName, + setMenuVisible, +}: OuterClickProps) { + const handleClick = (event: MouseEvent) => { + const targets = event.target as HTMLElement; + // Check if the click is outside the selectable-dropdown-wrapper + if (!targets.closest(`.${contextClassName}`)) { + setMenuVisible(false); // Close the menu by updating the state + } + }; + + // Add event listener on mount and remove it on unmount + React.useEffect(() => { + document.addEventListener("click", handleClick); + return () => { + document.removeEventListener("click", handleClick); + }; + }, []); + + return null; // This component doesn't render anything +} diff --git a/frontend/src/utils/theme.ts b/frontend/src/utils/theme.ts new file mode 100644 index 0000000..f04a310 --- /dev/null +++ b/frontend/src/utils/theme.ts @@ -0,0 +1,34 @@ +export {}; +// Function to set the theme based on user preference or system default +function setTheme() { + // Check for saved theme in localStorage + const savedTheme: string | null = localStorage.getItem('theme'); + + // If no saved theme, use system default preference + const systemPrefersDark: boolean = window.matchMedia('(prefers-color-scheme: dark)').matches; + const defaultTheme: string = savedTheme || (systemPrefersDark ? 'dark' : 'light'); + + // Set the theme on page load + document.documentElement.setAttribute('data-theme', defaultTheme); +} + +// Call the function to set the theme +setTheme(); + +// Check if the toggle button exists +const toggleSwitch: Element | null = document.querySelector('.theme-switch'); + +if (toggleSwitch) { + toggleSwitch.addEventListener('click', () => { + const currentTheme: string | null = document.documentElement.getAttribute('data-theme'); + + // Toggle between dark and light themes + const newTheme: string = currentTheme === 'dark' ? 'light' : 'dark'; + document.documentElement.setAttribute('data-theme', newTheme); + + // Save the new preference in localStorage + localStorage.setItem('theme', newTheme); + }); +} else { + console.warn("Theme switch button not found!"); +} diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json new file mode 100644 index 0000000..55baf3d --- /dev/null +++ b/frontend/tsconfig.json @@ -0,0 +1,60 @@ +{ + // Compiler options for TypeScript + "compilerOptions": { + // Specify ECMAScript target version + "target": "ES6", + + // Specify library files to be included in the compilation + "lib": [ + "dom", // DOM library for web development + "dom.iterable", // DOM iterable support + "esnext" // Latest ECMAScript features + ], + + // Allow JavaScript files to be compiled + "allowJs": true, + + // Skip type checking of declaration files + "skipLibCheck": true, + + // Enables emit interoperability between CommonJS and ES Modules + "esModuleInterop": true, + + // Allow default imports from modules with no default export + "allowSyntheticDefaultImports": true, + + // Enable all strict type-checking options + "strict": true, + + // Force consistent casing in file names + "forceConsistentCasingInFileNames": true, + + // Report errors for fallthrough cases in switch statements + "noFallthroughCasesInSwitch": true, + + // Specify module code generation + "module": "esnext", + + // Specify module resolution strategy + "moduleResolution": "node", + + // Include modules imported with .json extension + "resolveJsonModule": true, + + // Isolate each file in its own module + "isolatedModules": false, + + // Do not emit output files + "noEmit": true, + + // Specify JSX code generation + "jsx": "react-jsx" // Use the new JSX transform from React 17+ + }, + + // Specify the files to be included in the compilation + "include": [ + "src", // Include all files in the src directory + "scripts", // Include all files in the scripts directory + "types/declarations.d.ts" // Include custom type definitions + ] +}