diff --git a/ai_agents/.env.example b/ai_agents/.env.example index 046504aba7..1dfeb45e6a 100644 --- a/ai_agents/.env.example +++ b/ai_agents/.env.example @@ -14,6 +14,17 @@ WORKERS_MAX=100 # Worker quit timeout in seconds WORKER_QUIT_TIMEOUT_SECONDS=60 +# ------------------------------ +# Frontend +# ------------------------------ + +# API server URL for the web UI +AGENT_SERVER_URL=http://localhost:8080 +# TMAN Designer dev server URL for the web UI +TEN_DEV_SERVER_URL=http://localhost:49483 +# Enable edit graph mode in the UI +NEXT_PUBLIC_EDIT_GRAPH_MODE=true + # ------------------------------ # RTC # ------------------------------ diff --git a/ai_agents/agents/examples/doodler/.env.example b/ai_agents/agents/examples/doodler/.env.example new file mode 100644 index 0000000000..cb156a9325 --- /dev/null +++ b/ai_agents/agents/examples/doodler/.env.example @@ -0,0 +1,12 @@ +# Required Environment Variables + +# Agora RTC (for voice input) +AGORA_APP_ID=your_agora_app_id_here +AGORA_APP_CERTIFICATE=your_agora_certificate_here # Optional + +# OpenAI (for ASR, LLM, and Image Generation) +OPENAI_API_KEY=sk-your_openai_api_key_here + +# Optional Customization +OPENAI_MODEL=gpt-4o-mini # LLM model +OPENAI_BASE_URL=https://api.openai.com/v1 # Custom endpoint diff --git a/ai_agents/agents/examples/doodler/Dockerfile b/ai_agents/agents/examples/doodler/Dockerfile new file mode 100644 index 0000000000..f521a47a71 --- /dev/null +++ b/ai_agents/agents/examples/doodler/Dockerfile @@ -0,0 +1,83 @@ +FROM ghcr.io/ten-framework/ten_agent_build:0.7.12 AS builder + +ARG USE_AGENT=agents/examples/voice-assistant + +WORKDIR /app + +COPY .env.example .env +COPY server/ server/ +COPY agents/scripts/ agents/scripts/ +COPY agents/ten_packages/ agents/ten_packages/ +COPY ${USE_AGENT}/frontend/ ${USE_AGENT}/frontend/ + +# Copy tenapp files explicitly to avoid symlink issues +COPY ${USE_AGENT}/tenapp/go.* ${USE_AGENT}/tenapp/ +COPY ${USE_AGENT}/tenapp/main.go ${USE_AGENT}/tenapp/ +COPY ${USE_AGENT}/tenapp/manifest* ${USE_AGENT}/tenapp/ +COPY ${USE_AGENT}/tenapp/property.json ${USE_AGENT}/tenapp/ +COPY ${USE_AGENT}/tenapp/scripts/ ${USE_AGENT}/tenapp/scripts/ + +# Copy extension directories that are actual directories (not symlinks) +COPY ${USE_AGENT}/tenapp/ten_packages/extension/main_python/ ${USE_AGENT}/tenapp/ten_packages/extension/main_python/ + +# Copy other example files +COPY ${USE_AGENT}/README.md ${USE_AGENT}/ +COPY ${USE_AGENT}/Taskfile*.yml ${USE_AGENT}/ + +RUN cd /app/${USE_AGENT} && \ + task install && task release + +# Build frontend in builder stage (bun already done by task install) +WORKDIR /app/${USE_AGENT}/frontend +RUN NEXT_PUBLIC_EDIT_GRAPH_MODE=false bun run build +WORKDIR /app + +FROM ubuntu:22.04 + +ARG USE_AGENT=agents/examples/voice-assistant + +RUN apt-get clean && apt-get update && apt-get install -y --no-install-recommends \ + libasound2 \ + libgstreamer1.0-dev \ + libunwind-dev \ + libc++1 \ + libssl-dev \ + python3 \ + python3-venv \ + python3-pip \ + python3-dev \ + jq vim \ + ca-certificates \ + curl \ + unzip \ + && apt-get clean && rm -rf /var/lib/apt/lists/* && rm -rf /tmp/* + +# Install Node.js 20 +RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ + && apt-get install -y nodejs + +# Install Bun using the official install script +RUN curl -fsSL https://bun.com/install | bash +# Add Bun to the PATH (if not already added by the install script) +ENV PATH="/root/.bun/bin:$PATH" + +# Install Task +RUN sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin + +WORKDIR /app + +COPY --from=builder /app/${USE_AGENT}/tenapp/.release/ /app/agents/ +COPY --from=builder /app/server/bin/api /app/server/bin/api +COPY --from=builder /usr/local/lib /usr/local/lib +COPY --from=builder /usr/lib/python3 /usr/lib/python3 +COPY --from=builder /usr/local/bin/tman /usr/local/bin/tman + +# Copy built frontend from builder stage +COPY --from=builder /app/${USE_AGENT}/frontend/ /app/frontend/ + +# Copy Docker Taskfile +COPY --from=builder /app/${USE_AGENT}/Taskfile.docker.yml /app/Taskfile.docker.yml + +EXPOSE 8080 3000 + +ENTRYPOINT ["task", "-t", "Taskfile.docker.yml", "run-prod"] diff --git a/ai_agents/agents/examples/doodler/README.md b/ai_agents/agents/examples/doodler/README.md new file mode 100644 index 0000000000..8b347928db --- /dev/null +++ b/ai_agents/agents/examples/doodler/README.md @@ -0,0 +1,336 @@ +# Voice Image Kids - AI Art Generator for Children + +A delightful voice-to-image generation application built with TEN Framework. Kids speak what they want to draw, and AI creates it instantly! + +## Features + +- **Voice Activity Detection**: Automatic speech detection - no buttons needed! +- **Natural Speech Input**: Kids just talk naturally about what they want to create +- **GPT Image 1.5**: Latest, fastest OpenAI image generation (4x faster than DALL-E 3) +- **Kid-Friendly UI**: Colorful, engaging interface via dedicated doodler frontend +- **Instant Results**: Images appear in seconds +- **Safe & Encouraging**: Gentle error messages and positive feedback + +## How It Works + +1. **Kid speaks**: "I want a purple dragon flying over a rainbow castle!" +2. **AI listens**: OpenAI Whisper transcribes speech +3. **AI understands**: GPT-4o-mini processes the request +4. **AI creates**: GPT Image 1.5 generates the image +5. **Kid sees**: Image appears in the chat! + +## Prerequisites + +### Required API Keys + +1. **Agora Account** (for voice input) + - Sign up at [console.agora.io](https://console.agora.io/) + - Get your `AGORA_APP_ID` + +2. **OpenAI Account** (for everything else) + - Sign up at [platform.openai.com](https://platform.openai.com/) + - Get your `OPENAI_API_KEY` + - You'll need access to: + - Whisper (speech-to-text) + - GPT-4o-mini (language model) + - GPT Image 1.5 (image generation) + +### System Requirements + +- **Node.js**: >= 20 +- **Bun**: Latest version +- **Go**: For API server +- **Python**: 3.10+ (for TEN extensions) +- **TEN Framework**: Installed via `tman` + +## Quick Start + +### 1. Clone and Navigate + +```bash +cd ai_agents/agents/examples/doodler +``` + +### 2. Set Environment Variables + +Create a `.env` file in the root `ai_agents` directory: + +```bash +# Required +AGORA_APP_ID=your_agora_app_id +OPENAI_API_KEY=sk-your_openai_key + +# Optional +AGORA_APP_CERTIFICATE=your_certificate +OPENAI_MODEL=gpt-4o-mini +AGENT_SERVER_URL=http://localhost:8080 +TEN_DEV_SERVER_URL=http://localhost:49483 +NEXT_PUBLIC_EDIT_GRAPH_MODE=true +``` + +### 3. Install Dependencies + +```bash +task install +``` + +This will: +- Install TEN framework packages +- Install Python dependencies +- Install frontend +- Build the API server + +### 4. Run the App + +```bash +task run +``` + +This starts: +- TEN Runtime (agent backend) +- API Server (port 8080) +- TMAN Designer (port 49483) +- Frontend will be available from the doodler frontend + +Frontend source lives in `ai_agents/agents/examples/doodler/frontend`. + +### 5. Access the Application + +- **Frontend**: http://localhost:3000 +- **API Server**: http://localhost:8080 +- **TMAN Designer**: http://localhost:49483 + +## API Endpoints + +- `GET /graphs` lists available graphs in `tenapp/property.json` for the API server: + ``` + curl http://localhost:8080/graphs + ``` +- `POST /start` launches a worker with the selected graph and optional property overrides: + ``` + curl -X POST http://localhost:8080/start \ + -H 'Content-Type: application/json' \ + -d '{ + "request_id":"any-id", + "channel_name":"kids_demo", + "user_uid":10001, + "graph_name":"voice_image_kids", + "properties":{} + }' + ``` + +## Usage + +1. Open http://localhost:3000 in your browser +2. Allow microphone access when prompted +3. Start speaking! For example: + - "I want a spaceship in outer space!" + - "Draw a cute puppy playing in a park" + - "Create a magical fairy castle with rainbows" +4. Watch as the AI creates your image! + +## Configuration + +### Agent Graph + +The app uses these components: + +- **agora_rtc**: Audio I/O with voice activity detection +- **openai_asr_python**: Speech-to-text (Whisper) +- **openai_llm2_python**: Language model (GPT-4o-mini) +- **openai_gpt_image_python**: Image generation (GPT Image 1.5) +- **main_python**: Orchestration +- **message_collector**: Chat history + +### Customization + +Edit `tenapp/property.json` to customize: + +**LLM Prompt** (make it more/less kid-friendly): +```json +{ + "nodes": [{ + "name": "llm", + "property": { + "prompt": "Your custom system prompt here..." + } + }] +} +``` + +**Image Settings**: +```json +{ + "nodes": [{ + "name": "image_gen_tool", + "property": { + "params": { + "model": "gpt-image-1.5", // or "dall-e-3" + "size": "1024x1024", // or "1792x1024", "1024x1792" + "quality": "standard" // or "hd" for higher quality + } + } + }] +} +``` + +## Project Structure + +``` +doodler/ +├── tenapp/ +│ ├── property.json # Agent graph configuration +│ ├── manifest.json # App metadata +│ └── ten_packages/ +│ └── extension/ +│ └── main_python/ # Main control logic +│ ├── extension.py # Event handlers +│ ├── config.py # Configuration +│ └── agent/ # Agent framework +├── Taskfile.yml # Build & run automation +├── Dockerfile # Container deployment +├── .env.example # Environment template +└── README.md # This file +``` + +## Troubleshooting + +### No Voice Input Detected + +- Check microphone permissions in browser +- Verify `AGORA_APP_ID` is set correctly +- Check browser console for errors + +### Images Not Generating + +- Verify `OPENAI_API_KEY` has access to GPT Image 1.5 +- Check TEN runtime logs: `tail -f tenapp/logs/latest.log` +- Try fallback model (DALL-E 3) in configuration + +### "API key is invalid" + +- Double-check `OPENAI_API_KEY` in `.env` +- Ensure no extra spaces or quotes +- Verify key is active on OpenAI platform + +### Installation Fails + +```bash +# Clean install +cd tenapp +rm -rf ten_packages +tman install +./scripts/install_python_deps.sh +``` + +## Docker Deployment + +### Build Image + +```bash +cd ai_agents +docker build -f agents/examples/doodler/Dockerfile -t doodler . +``` + +### Run Container + +```bash +docker run --rm -it --env-file .env \ + -p 8080:8080 \ + -p 3000:3000 \ + -p 49483:49483 \ + doodler +``` + +### Access + +- Frontend: http://localhost:3000 +- API: http://localhost:8080 +- TMAN Designer: http://localhost:49483 + +## Development + +### Visual Graph Designer + +Access TMAN Designer at http://localhost:49483 to: +- Visualize the agent graph +- Modify connections visually +- Test different configurations +- Add new extensions + +### Adding New Features + +1. **Add a new extension** to `tenapp/property.json` +2. **Configure connections** in the graph +3. **Update main_python** to handle new events +4. **Test** with `task run` + +### Debugging + +Enable debug mode in `tenapp/property.json`: + +```json +{ + "nodes": [{ + "name": "image_gen_tool", + "property": { + "dump": true, + "dump_path": "./debug_images.json" + } + }] +} +``` + +View logs: +```bash +# TEN runtime logs +tail -f tenapp/logs/latest.log + +# API server logs +# (shown in terminal where you ran `task run`) +``` + +## Safety & Content Policy + +The app uses OpenAI's content policy filtering. If an image request violates policies, kids will see: +> "I can't create that image. Let's try something different!" + +The LLM is configured to be encouraging and kid-friendly. + +## Performance + +- **Voice-to-Text**: ~500ms (Whisper) +- **LLM Processing**: ~1-2s (GPT-4o-mini) +- **Image Generation**: ~3-5s (GPT Image 1.5) - 4x faster than DALL-E 3! +- **Total**: ~5-8 seconds from speech to image + +## Cost Estimation + +Per image generation: +- Whisper transcription: ~$0.006/minute +- GPT-4o-mini: ~$0.001 (for prompt processing) +- GPT Image 1.5 (1024x1024, standard): ~$0.04 +- **Total per image**: ~$0.05 + +(Prices as of December 2024, may vary) + +## Learn More + +- [TEN Framework Documentation](https://doc.theten.ai) +- [OpenAI Image Generation Guide](https://platform.openai.com/docs/guides/image-generation) +- [GPT Image 1.5 Announcement](https://openai.com/index/new-chatgpt-images-is-here/) +- [Agora RTC Documentation](https://docs.agora.io/en/) + +## License + +This example is part of the TEN Framework, licensed under the Apache License, Version 2.0. + +## Support + +- **TEN Framework Issues**: [github.com/TEN-framework/TEN-Agent](https://github.com/TEN-framework/TEN-Agent) +- **OpenAI Support**: [help.openai.com](https://help.openai.com/) +- **Agora Support**: [agora.io/support](https://www.agora.io/en/customer-support/) + +--- + +**Have fun creating amazing art with AI!** 🎨✨ diff --git a/ai_agents/agents/examples/doodler/Taskfile.yml b/ai_agents/agents/examples/doodler/Taskfile.yml new file mode 100644 index 0000000000..729b474c7e --- /dev/null +++ b/ai_agents/agents/examples/doodler/Taskfile.yml @@ -0,0 +1,80 @@ +version: "3" + +dotenv: ["../../../.env"] + +tasks: + # install scripts + install-frontend: + desc: install frontend dependencies + internal: true + dir: ./frontend + cmds: + - bun install --verbose + + install-tenapp: + desc: install tenapp dependencies + internal: true + dir: ./tenapp + cmds: + - tman install + + install-tenapp-python-deps: + desc: install tenapp python dependencies + deps: [install-tenapp] + internal: true + dir: ./tenapp + cmds: + - ./scripts/install_python_deps.sh + + build-api-server: + desc: build api server + dir: ../../../server + cmds: + - go mod tidy && go mod download && go build -o bin/api main.go + + install: + desc: install all dependencies + dir: ./tenapp + cmds: + - task: install-tenapp + - task: install-tenapp-python-deps + - task: install-frontend + - task: build-api-server + + # run scripts + run-tenapp: + desc: run tenapp + dir: ./tenapp + cmds: + - tman run start + + run-gd-server: + desc: run tman dev http server for TMAN Designer + dir: ./tenapp + cmds: + - tman designer + + run-frontend: + desc: run frontend + dir: ./frontend + cmds: + - bun run dev + + run-api-server: + desc: run api server + dir: ../../../server + cmds: + - ./bin/api -tenapp_dir={{.PWD}}/tenapp + + run: + desc: run everything + deps: + - task: run-gd-server + - task: run-frontend + - task: run-api-server + + # release scripts + release: + desc: release + cmds: + - ../../scripts/release.sh {{.PWD}}/tenapp diff --git a/ai_agents/agents/examples/doodler/frontend/.dockerignore b/ai_agents/agents/examples/doodler/frontend/.dockerignore new file mode 100644 index 0000000000..80ae13cefd --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/.dockerignore @@ -0,0 +1,3 @@ +.git +.next +node_modules diff --git a/ai_agents/agents/examples/doodler/frontend/.gitignore b/ai_agents/agents/examples/doodler/frontend/.gitignore new file mode 100644 index 0000000000..7b1d7426ac --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/.gitignore @@ -0,0 +1,135 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +# .env +!.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* +.yarn + +# Claude Code +.claude \ No newline at end of file diff --git a/ai_agents/agents/examples/doodler/frontend/Dockerfile b/ai_agents/agents/examples/doodler/frontend/Dockerfile new file mode 100644 index 0000000000..157cb48399 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/Dockerfile @@ -0,0 +1,68 @@ +# syntax=docker.io/docker/dockerfile:1 + +FROM oven/bun:alpine AS base + +# 1. Install dependencies only when needed +FROM base AS deps +# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. +RUN apk add --no-cache libc6-compat + +WORKDIR /app + +# Install dependencies based on the preferred package manager +COPY package.json bun.lock ./ +RUN \ + if [ -f bun.lockb ]; then bun i --frozen-lockfile; \ + elif [ -f bun.lock ]; then bun i --frozen-lockfile; \ + else echo "Lockfile not found." && exit 1; \ + fi + +# 2. Rebuild the source code only when needed +FROM base AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +# Next.js collects completely anonymous telemetry data about general usage. +# Learn more here: https://nextjs.org/telemetry +# Uncomment the following line in case you want to disable telemetry during the build. +ENV NEXT_TELEMETRY_DISABLED=1 + +RUN \ + if [ -f bun.lockb ]; then bun run build; \ + elif [ -f bun.lock ]; then bun run build; \ + else echo "Lockfile not found." && exit 1; \ + fi + +# 3. Production image, copy all the files and run next +FROM base AS runner +WORKDIR /app + +# Uncomment the following line in case you want to disable telemetry during runtime. +ENV NEXT_TELEMETRY_DISABLED=1 + +ENV NODE_ENV=production + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +# COPY --from=builder /app/public ./public + +# Set the correct permission for prerender cache +RUN mkdir .next +RUN chown nextjs:nodejs .next + +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs + +EXPOSE 3000 + +ENV PORT=3000 + +# server.js is created by next build from the standalone output +# https://nextjs.org/docs/pages/api-reference/next-config-js/output +CMD HOSTNAME="0.0.0.0" node server.js diff --git a/ai_agents/agents/examples/doodler/frontend/LICENSE b/ai_agents/agents/examples/doodler/frontend/LICENSE new file mode 100644 index 0000000000..e4589a2b76 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Agora Community + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/ai_agents/agents/examples/doodler/frontend/README.md b/ai_agents/agents/examples/doodler/frontend/README.md new file mode 100644 index 0000000000..be7ffafb7f --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/README.md @@ -0,0 +1,22 @@ +## Doodler Frontend + +This is the dedicated UI for the Doodler example. + +### Prerequisites + +- Node.js >= 20 +- Bun (latest) + +### Install dependencies + +```bash +bun install +``` + +### Run dev server + +```bash +bun run dev +``` + +The UI expects the API server at `http://localhost:8080` (override with `AGENT_SERVER_URL` if needed). diff --git a/ai_agents/agents/examples/doodler/frontend/biome.json b/ai_agents/agents/examples/doodler/frontend/biome.json new file mode 100644 index 0000000000..52a1d9f2fb --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/biome.json @@ -0,0 +1,3 @@ +{ + "extends": ["../../biome.json"] +} diff --git a/ai_agents/agents/examples/doodler/frontend/bun.lock b/ai_agents/agents/examples/doodler/frontend/bun.lock new file mode 100644 index 0000000000..cc31dbe249 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/bun.lock @@ -0,0 +1,1081 @@ +{ + "lockfileVersion": 1, + "configVersion": 0, + "workspaces": { + "": { + "name": "ten_agent_playground", + "dependencies": { + "@hookform/resolvers": "^3.10.0", + "@radix-ui/react-avatar": "^1.1.10", + "@radix-ui/react-checkbox": "^1.3.3", + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-dropdown-menu": "^2.1.16", + "@radix-ui/react-label": "^2.1.7", + "@radix-ui/react-popover": "^1.1.15", + "@radix-ui/react-progress": "^1.1.7", + "@radix-ui/react-select": "^2.2.6", + "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-switch": "^1.2.6", + "@radix-ui/react-tabs": "^1.1.13", + "@radix-ui/react-tooltip": "^1.2.8", + "@reduxjs/toolkit": "^2.9.2", + "@trulience/react-sdk": "^1.0.98", + "agora-rtc-sdk-ng": "^4.23.0", + "agora-rtm": "^2.2.3", + "axios": "^1.13.1", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "framer-motion": "^12.23.26", + "lucide-react": "^0.546.0", + "next": "16.0.1", + "next-themes": "^0.4.6", + "protobufjs": "^7.5.4", + "react": "19.2.0", + "react-colorful": "^5.6.1", + "react-dom": "19.2.0", + "react-hook-form": "^7.65.0", + "react-redux": "^9.2.0", + "redux": "^5.0.1", + "sonner": "^1.7.4", + "tailwind-merge": "^2.6.0", + "tailwindcss-animate": "^1.0.7", + "zod": "^3.25.76", + }, + "devDependencies": { + "@biomejs/biome": "2.1.4", + "@minko-fe/postcss-pxtoviewport": "^1.5.0", + "@svgr/webpack": "^8.1.0", + "@tailwindcss/postcss": "^4.1.16", + "@types/node": "^20.19.24", + "@types/react": "19.2.2", + "@types/react-dom": "19.2.2", + "@types/react-redux": "^7.1.34", + "postcss": "^8.5.6", + "protobufjs-cli": "^1.1.3", + "tailwindcss": "^4.1.16", + "typescript": "^5.9.3", + }, + }, + }, + "overrides": { + "@types/react": "19.2.2", + "@types/react-dom": "19.2.2", + }, + "packages": { + "@agora-js/media": ["@agora-js/media@4.24.0", "", { "dependencies": { "@agora-js/report": "4.24.0", "@agora-js/shared": "4.24.0", "agora-rte-extension": "^1.2.4", "axios": "^1.8.3", "webrtc-adapter": "8.2.0" } }, "sha512-foii2klr5+qonLznxN0ZZFejoxLt/W8do79wmIsADPZLw2uZjRP35m0lqUGiLXBKeQ8u3i4UygPzEdFaY26hrw=="], + + "@agora-js/report": ["@agora-js/report@4.24.0", "", { "dependencies": { "@agora-js/shared": "4.24.0", "axios": "^1.8.3" } }, "sha512-MYbtkdY1Ls0KW0iagUzrPzyvqMWlyCWSC5odEb1SQaraAl7DJeDUkf91a3wxKzrjVah+LCxFxsS4lCFDxvKgNA=="], + + "@agora-js/shared": ["@agora-js/shared@4.24.0", "", { "dependencies": { "axios": "^1.8.3", "ua-parser-js": "^0.7.34" } }, "sha512-Vj67ZcTHZI+1ctWusrEPSSGLM3l6CFiAze/Bi8r7YHRMLivzhZR79nV6GiKvHS3muLAON2YAExznvjPIly6lcg=="], + + "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], + + "@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="], + + "@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], + + "@babel/compat-data": ["@babel/compat-data@7.27.5", "", {}, "sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg=="], + + "@babel/core": ["@babel/core@7.27.4", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.27.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.27.3", "@babel/helpers": "^7.27.4", "@babel/parser": "^7.27.4", "@babel/template": "^7.27.2", "@babel/traverse": "^7.27.4", "@babel/types": "^7.27.3", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g=="], + + "@babel/generator": ["@babel/generator@7.27.5", "", { "dependencies": { "@babel/parser": "^7.27.5", "@babel/types": "^7.27.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" } }, "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw=="], + + "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="], + + "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.27.2", "", { "dependencies": { "@babel/compat-data": "^7.27.2", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ=="], + + "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.27.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A=="], + + "@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "regexpu-core": "^6.2.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ=="], + + "@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.4", "", { "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" } }, "sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw=="], + + "@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA=="], + + "@babel/helper-module-imports": ["@babel/helper-module-imports@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w=="], + + "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.27.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.27.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg=="], + + "@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="], + + "@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.27.1", "", {}, "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw=="], + + "@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA=="], + + "@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="], + + "@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="], + + "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.27.1", "", {}, "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow=="], + + "@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="], + + "@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.27.1", "", { "dependencies": { "@babel/template": "^7.27.1", "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-NFJK2sHUvrjo8wAU/nQTWU890/zB2jj0qBcCbZbbf+005cAsv6tMjXz31fBign6M5ov1o0Bllu+9nbqkfsjjJQ=="], + + "@babel/helpers": ["@babel/helpers@7.27.6", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.27.6" } }, "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug=="], + + "@babel/parser": ["@babel/parser@7.27.5", "", { "dependencies": { "@babel/types": "^7.27.3" }, "bin": "./bin/babel-parser.js" }, "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg=="], + + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": ["@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA=="], + + "@babel/plugin-bugfix-safari-class-field-initializer-scope": ["@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA=="], + + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ["@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA=="], + + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ["@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.13.0" } }, "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw=="], + + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ["@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-6BpaYGDavZqkI6yT+KSPdpZFfpnd68UKXbcjI9pJ13pvHhPrCKWOOLp+ysvMeA+DxnhuPpgIaRpxRxo5A9t5jw=="], + + "@babel/plugin-proposal-private-property-in-object": ["@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2", "", { "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w=="], + + "@babel/plugin-syntax-import-assertions": ["@babel/plugin-syntax-import-assertions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg=="], + + "@babel/plugin-syntax-import-attributes": ["@babel/plugin-syntax-import-attributes@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww=="], + + "@babel/plugin-syntax-jsx": ["@babel/plugin-syntax-jsx@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w=="], + + "@babel/plugin-syntax-typescript": ["@babel/plugin-syntax-typescript@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ=="], + + "@babel/plugin-syntax-unicode-sets-regex": ["@babel/plugin-syntax-unicode-sets-regex@7.18.6", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg=="], + + "@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA=="], + + "@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-eST9RrwlpaoJBDHShc+DS2SG4ATTi2MYNb4OxYkf3n+7eb49LWpnS+HSpVfW4x927qQwgk8A2hGNVaajAEw0EA=="], + + "@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA=="], + + "@babel/plugin-transform-block-scoped-functions": ["@babel/plugin-transform-block-scoped-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg=="], + + "@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.27.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-JF6uE2s67f0y2RZcm2kpAUEbD50vH62TyWVebxwHAlbSdM49VqPz8t4a1uIjp4NIOIZ4xzLfjY5emt/RCyC7TQ=="], + + "@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA=="], + + "@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-s734HmYU78MVzZ++joYM+NkJusItbdRcbm+AGRgJCt3iA+yux0QpD9cBVdz3tKyrjVYWRl7j0mHSmv4lhV0aoA=="], + + "@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-compilation-targets": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/traverse": "^7.27.1", "globals": "^11.1.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-7iLhfFAubmpeJe/Wo2TVuDrykh/zlWXLzPNdL0Jqn/Xu8R3QQ8h9ff8FQoISZOsw74/HFqFI7NX63HN7QFIHKA=="], + + "@babel/plugin-transform-computed-properties": ["@babel/plugin-transform-computed-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/template": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw=="], + + "@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.27.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-s4Jrok82JpiaIprtY2nHsYmrThKvvwgHwjgd7UMiYhZaN0asdXNLr0y+NjTfkA7SyQE5i2Fb7eawUOZmLvyqOA=="], + + "@babel/plugin-transform-dotall-regex": ["@babel/plugin-transform-dotall-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw=="], + + "@babel/plugin-transform-duplicate-keys": ["@babel/plugin-transform-duplicate-keys@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q=="], + + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": ["@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ=="], + + "@babel/plugin-transform-dynamic-import": ["@babel/plugin-transform-dynamic-import@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A=="], + + "@babel/plugin-transform-exponentiation-operator": ["@babel/plugin-transform-exponentiation-operator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ=="], + + "@babel/plugin-transform-export-namespace-from": ["@babel/plugin-transform-export-namespace-from@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ=="], + + "@babel/plugin-transform-for-of": ["@babel/plugin-transform-for-of@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw=="], + + "@babel/plugin-transform-function-name": ["@babel/plugin-transform-function-name@7.27.1", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ=="], + + "@babel/plugin-transform-json-strings": ["@babel/plugin-transform-json-strings@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q=="], + + "@babel/plugin-transform-literals": ["@babel/plugin-transform-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA=="], + + "@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw=="], + + "@babel/plugin-transform-member-expression-literals": ["@babel/plugin-transform-member-expression-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ=="], + + "@babel/plugin-transform-modules-amd": ["@babel/plugin-transform-modules-amd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA=="], + + "@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="], + + "@babel/plugin-transform-modules-systemjs": ["@babel/plugin-transform-modules-systemjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA=="], + + "@babel/plugin-transform-modules-umd": ["@babel/plugin-transform-modules-umd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w=="], + + "@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng=="], + + "@babel/plugin-transform-new-target": ["@babel/plugin-transform-new-target@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ=="], + + "@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA=="], + + "@babel/plugin-transform-numeric-separator": ["@babel/plugin-transform-numeric-separator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw=="], + + "@babel/plugin-transform-object-rest-spread": ["@babel/plugin-transform-object-rest-spread@7.27.3", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.27.3", "@babel/plugin-transform-parameters": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-7ZZtznF9g4l2JCImCo5LNKFHB5eXnN39lLtLY5Tg+VkR0jwOt7TBciMckuiQIOIW7L5tkQOCh3bVGYeXgMx52Q=="], + + "@babel/plugin-transform-object-super": ["@babel/plugin-transform-object-super@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng=="], + + "@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q=="], + + "@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg=="], + + "@babel/plugin-transform-parameters": ["@babel/plugin-transform-parameters@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-018KRk76HWKeZ5l4oTj2zPpSh+NbGdt0st5S6x0pga6HgrjBOJb24mMDHorFopOOd6YHkLgOZ+zaCjZGPO4aKg=="], + + "@babel/plugin-transform-private-methods": ["@babel/plugin-transform-private-methods@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA=="], + + "@babel/plugin-transform-private-property-in-object": ["@babel/plugin-transform-private-property-in-object@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ=="], + + "@babel/plugin-transform-property-literals": ["@babel/plugin-transform-property-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ=="], + + "@babel/plugin-transform-react-constant-elements": ["@babel/plugin-transform-react-constant-elements@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug=="], + + "@babel/plugin-transform-react-display-name": ["@babel/plugin-transform-react-display-name@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-p9+Vl3yuHPmkirRrg021XiP+EETmPMQTLr6Ayjj85RLNEbb3Eya/4VI0vAdzQG9SEAl2Lnt7fy5lZyMzjYoZQQ=="], + + "@babel/plugin-transform-react-jsx": ["@babel/plugin-transform-react-jsx@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/types": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw=="], + + "@babel/plugin-transform-react-jsx-development": ["@babel/plugin-transform-react-jsx-development@7.27.1", "", { "dependencies": { "@babel/plugin-transform-react-jsx": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q=="], + + "@babel/plugin-transform-react-pure-annotations": ["@babel/plugin-transform-react-pure-annotations@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA=="], + + "@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.27.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-uhB8yHerfe3MWnuLAhEbeQ4afVoqv8BQsPqrTv7e/jZ9y00kJL6l9a/f4OWaKxotmjzewfEyXE1vgDJenkQ2/Q=="], + + "@babel/plugin-transform-regexp-modifiers": ["@babel/plugin-transform-regexp-modifiers@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA=="], + + "@babel/plugin-transform-reserved-words": ["@babel/plugin-transform-reserved-words@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw=="], + + "@babel/plugin-transform-shorthand-properties": ["@babel/plugin-transform-shorthand-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ=="], + + "@babel/plugin-transform-spread": ["@babel/plugin-transform-spread@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q=="], + + "@babel/plugin-transform-sticky-regex": ["@babel/plugin-transform-sticky-regex@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g=="], + + "@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg=="], + + "@babel/plugin-transform-typeof-symbol": ["@babel/plugin-transform-typeof-symbol@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw=="], + + "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Q5sT5+O4QUebHdbwKedFBEwRLb02zJ7r4A5Gg2hUoLuU3FjdMcyqcywqUrLCaDsFCxzokf7u9kuy7qz51YUuAg=="], + + "@babel/plugin-transform-unicode-escapes": ["@babel/plugin-transform-unicode-escapes@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg=="], + + "@babel/plugin-transform-unicode-property-regex": ["@babel/plugin-transform-unicode-property-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q=="], + + "@babel/plugin-transform-unicode-regex": ["@babel/plugin-transform-unicode-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw=="], + + "@babel/plugin-transform-unicode-sets-regex": ["@babel/plugin-transform-unicode-sets-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw=="], + + "@babel/preset-env": ["@babel/preset-env@7.27.2", "", { "dependencies": { "@babel/compat-data": "^7.27.2", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.27.1", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.27.1", "@babel/plugin-syntax-import-attributes": "^7.27.1", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.27.1", "@babel/plugin-transform-async-generator-functions": "^7.27.1", "@babel/plugin-transform-async-to-generator": "^7.27.1", "@babel/plugin-transform-block-scoped-functions": "^7.27.1", "@babel/plugin-transform-block-scoping": "^7.27.1", "@babel/plugin-transform-class-properties": "^7.27.1", "@babel/plugin-transform-class-static-block": "^7.27.1", "@babel/plugin-transform-classes": "^7.27.1", "@babel/plugin-transform-computed-properties": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.27.1", "@babel/plugin-transform-dotall-regex": "^7.27.1", "@babel/plugin-transform-duplicate-keys": "^7.27.1", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-dynamic-import": "^7.27.1", "@babel/plugin-transform-exponentiation-operator": "^7.27.1", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-for-of": "^7.27.1", "@babel/plugin-transform-function-name": "^7.27.1", "@babel/plugin-transform-json-strings": "^7.27.1", "@babel/plugin-transform-literals": "^7.27.1", "@babel/plugin-transform-logical-assignment-operators": "^7.27.1", "@babel/plugin-transform-member-expression-literals": "^7.27.1", "@babel/plugin-transform-modules-amd": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-modules-systemjs": "^7.27.1", "@babel/plugin-transform-modules-umd": "^7.27.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-new-target": "^7.27.1", "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", "@babel/plugin-transform-numeric-separator": "^7.27.1", "@babel/plugin-transform-object-rest-spread": "^7.27.2", "@babel/plugin-transform-object-super": "^7.27.1", "@babel/plugin-transform-optional-catch-binding": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.27.1", "@babel/plugin-transform-parameters": "^7.27.1", "@babel/plugin-transform-private-methods": "^7.27.1", "@babel/plugin-transform-private-property-in-object": "^7.27.1", "@babel/plugin-transform-property-literals": "^7.27.1", "@babel/plugin-transform-regenerator": "^7.27.1", "@babel/plugin-transform-regexp-modifiers": "^7.27.1", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", "@babel/plugin-transform-spread": "^7.27.1", "@babel/plugin-transform-sticky-regex": "^7.27.1", "@babel/plugin-transform-template-literals": "^7.27.1", "@babel/plugin-transform-typeof-symbol": "^7.27.1", "@babel/plugin-transform-unicode-escapes": "^7.27.1", "@babel/plugin-transform-unicode-property-regex": "^7.27.1", "@babel/plugin-transform-unicode-regex": "^7.27.1", "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.10", "babel-plugin-polyfill-corejs3": "^0.11.0", "babel-plugin-polyfill-regenerator": "^0.6.1", "core-js-compat": "^3.40.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Ma4zSuYSlGNRlCLO+EAzLnCmJK2vdstgv+n7aUP+/IKZrOfWHOJVdSJtuub8RzHTj3ahD37k5OKJWvzf16TQyQ=="], + + "@babel/preset-modules": ["@babel/preset-modules@0.1.6-no-external-plugins", "", { "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" } }, "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA=="], + + "@babel/preset-react": ["@babel/preset-react@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-transform-react-display-name": "^7.27.1", "@babel/plugin-transform-react-jsx": "^7.27.1", "@babel/plugin-transform-react-jsx-development": "^7.27.1", "@babel/plugin-transform-react-pure-annotations": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-oJHWh2gLhU9dW9HHr42q0cI0/iHHXTLGe39qvpAZZzagHy0MzYLCnCVV0symeRvzmjHyVU7mw2K06E6u/JwbhA=="], + + "@babel/preset-typescript": ["@babel/preset-typescript@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ=="], + + "@babel/runtime": ["@babel/runtime@7.27.6", "", {}, "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q=="], + + "@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + + "@babel/traverse": ["@babel/traverse@7.27.4", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.27.3", "@babel/parser": "^7.27.4", "@babel/template": "^7.27.2", "@babel/types": "^7.27.3", "debug": "^4.3.1", "globals": "^11.1.0" } }, "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA=="], + + "@babel/types": ["@babel/types@7.27.6", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q=="], + + "@biomejs/biome": ["@biomejs/biome@2.1.4", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.1.4", "@biomejs/cli-darwin-x64": "2.1.4", "@biomejs/cli-linux-arm64": "2.1.4", "@biomejs/cli-linux-arm64-musl": "2.1.4", "@biomejs/cli-linux-x64": "2.1.4", "@biomejs/cli-linux-x64-musl": "2.1.4", "@biomejs/cli-win32-arm64": "2.1.4", "@biomejs/cli-win32-x64": "2.1.4" }, "bin": { "biome": "bin/biome" } }, "sha512-QWlrqyxsU0FCebuMnkvBIkxvPqH89afiJzjMl+z67ybutse590jgeaFdDurE9XYtzpjRGTI1tlUZPGWmbKsElA=="], + + "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.1.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-sCrNENE74I9MV090Wq/9Dg7EhPudx3+5OiSoQOkIe3DLPzFARuL1dOwCWhKCpA3I5RHmbrsbNSRfZwCabwd8Qg=="], + + "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.1.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-gOEICJbTCy6iruBywBDcG4X5rHMbqCPs3clh3UQ+hRKlgvJTk4NHWQAyHOXvaLe+AxD1/TNX1jbZeffBJzcrOw=="], + + "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.1.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-juhEkdkKR4nbUi5k/KRp1ocGPNWLgFRD4NrHZSveYrD6i98pyvuzmS9yFYgOZa5JhaVqo0HPnci0+YuzSwT2fw=="], + + "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.1.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-nYr7H0CyAJPaLupFE2cH16KZmRC5Z9PEftiA2vWxk+CsFkPZQ6dBRdcC6RuS+zJlPc/JOd8xw3uCCt9Pv41WvQ=="], + + "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.1.4", "", { "os": "linux", "cpu": "x64" }, "sha512-Eoy9ycbhpJVYuR+LskV9s3uyaIkp89+qqgqhGQsWnp/I02Uqg2fXFblHJOpGZR8AxdB9ADy87oFVxn9MpFKUrw=="], + + "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.1.4", "", { "os": "linux", "cpu": "x64" }, "sha512-lvwvb2SQQHctHUKvBKptR6PLFCM7JfRjpCCrDaTmvB7EeZ5/dQJPhTYBf36BE/B4CRWR2ZiBLRYhK7hhXBCZAg=="], + + "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.1.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-3WRYte7orvyi6TRfIZkDN9Jzoogbv+gSvR+b9VOXUg1We1XrjBg6WljADeVEaKTvOcpVdH0a90TwyOQ6ue4fGw=="], + + "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.1.4", "", { "os": "win32", "cpu": "x64" }, "sha512-tBc+W7anBPSFXGAoQW+f/+svkpt8/uXfRwDzN1DvnatkRMt16KIYpEi/iw8u9GahJlFv98kgHcIrSsZHZTR0sw=="], + + "@emnapi/runtime": ["@emnapi/runtime@1.5.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="], + + "@floating-ui/core": ["@floating-ui/core@1.7.1", "", { "dependencies": { "@floating-ui/utils": "^0.2.9" } }, "sha512-azI0DrjMMfIug/ExbBaeDVJXcY0a7EPvPjb2xAJPa4HeimBX+Z18HK8QQR3jb6356SnDDdxx+hinMLcJEDdOjw=="], + + "@floating-ui/dom": ["@floating-ui/dom@1.7.1", "", { "dependencies": { "@floating-ui/core": "^1.7.1", "@floating-ui/utils": "^0.2.9" } }, "sha512-cwsmW/zyw5ltYTUeeYJ60CnQuPqmGwuGVhG9w0PRaRKkAyi38BT5CKrpIbb+jtahSwUl04cWzSx9ZOIxeS6RsQ=="], + + "@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.3", "", { "dependencies": { "@floating-ui/dom": "^1.0.0" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-huMBfiU9UnQ2oBwIhgzyIiSpVgvlDstU8CX0AF+wS+KzmYMs0J2a3GwuFHV1Lz+jlrQGeC1fF+Nv0QoumyV0bA=="], + + "@floating-ui/utils": ["@floating-ui/utils@0.2.9", "", {}, "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg=="], + + "@hookform/resolvers": ["@hookform/resolvers@3.10.0", "", { "peerDependencies": { "react-hook-form": "^7.0.0" } }, "sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag=="], + + "@img/colour": ["@img/colour@1.0.0", "", {}, "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw=="], + + "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.3" }, "os": "darwin", "cpu": "arm64" }, "sha512-sitdlPzDVyvmINUdJle3TNHl+AG9QcwiAMsXmccqsCOMZNIdW2/7S26w0LyU8euiLVzFBL3dXPwVCq/ODnf2vA=="], + + "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.3" }, "os": "darwin", "cpu": "x64" }, "sha512-rZheupWIoa3+SOdF/IcUe1ah4ZDpKBGWcsPX6MT0lYniH9micvIU7HQkYTfrx5Xi8u+YqwLtxC/3vl8TQN6rMg=="], + + "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw=="], + + "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-Ju+g2xn1E2AKO6YBhxjj+ACcsPQRHT0bhpglxcEf+3uyPY+/gL8veniKoo96335ZaPo03bdDXMv0t+BBFAbmRA=="], + + "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.3", "", { "os": "linux", "cpu": "arm" }, "sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA=="], + + "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ=="], + + "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg=="], + + "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-RgWrs/gVU7f+K7P+KeHFaBAJlNkD1nIZuVXdQv6S+fNA6syCcoboNjsV2Pou7zNlVdNQoQUpQTk8SWDHUA3y/w=="], + + "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.3", "", { "os": "linux", "cpu": "x64" }, "sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg=="], + + "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-F9q83RZ8yaCwENw1GieztSfj5msz7GGykG/BA+MOUefvER69K/ubgFHNeSyUu64amHIYKGDs4sRCMzXVj8sEyw=="], + + "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.3", "", { "os": "linux", "cpu": "x64" }, "sha512-U5PUY5jbc45ANM6tSJpsgqmBF/VsL6LnxJmIf11kB7J5DctHgqm0SkuXzVWtIY90GnJxKnC/JT251TDnk1fu/g=="], + + "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.3" }, "os": "linux", "cpu": "arm" }, "sha512-Xyam4mlqM0KkTHYVSuc6wXRmM7LGN0P12li03jAnZ3EJWZqj83+hi8Y9UxZUbxsgsK1qOEwg7O0Bc0LjqQVtxA=="], + + "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.3" }, "os": "linux", "cpu": "arm64" }, "sha512-YXU1F/mN/Wu786tl72CyJjP/Ngl8mGHN1hST4BGl+hiW5jhCnV2uRVTNOcaYPs73NeT/H8Upm3y9582JVuZHrQ=="], + + "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.3" }, "os": "linux", "cpu": "ppc64" }, "sha512-F4PDtF4Cy8L8hXA2p3TO6s4aDt93v+LKmpcYFLAVdkkD3hSxZzee0rh6/+94FpAynsuMpLX5h+LRsSG3rIciUQ=="], + + "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.3" }, "os": "linux", "cpu": "s390x" }, "sha512-qVrZKE9Bsnzy+myf7lFKvng6bQzhNUAYcVORq2P7bDlvmF6u2sCmK2KyEQEBdYk+u3T01pVsPrkj943T1aJAsw=="], + + "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.3" }, "os": "linux", "cpu": "x64" }, "sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A=="], + + "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.3" }, "os": "linux", "cpu": "arm64" }, "sha512-8hDVvW9eu4yHWnjaOOR8kHVrew1iIX+MUgwxSuH2XyYeNRtLUe4VNioSqbNkB7ZYQJj9rUTT4PyRscyk2PXFKA=="], + + "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.3" }, "os": "linux", "cpu": "x64" }, "sha512-lU0aA5L8QTlfKjpDCEFOZsTYGn3AEiO6db8W5aQDxj0nQkVrZWmN3ZP9sYKWJdtq3PWPhUNlqehWyXpYDcI9Sg=="], + + "@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.4", "", { "dependencies": { "@emnapi/runtime": "^1.5.0" }, "cpu": "none" }, "sha512-33QL6ZO/qpRyG7woB/HUALz28WnTMI2W1jgX3Nu2bypqLIKx/QKMILLJzJjI+SIbvXdG9fUnmrxR7vbi1sTBeA=="], + + "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-2Q250do/5WXTwxW3zjsEuMSv5sUU4Tq9VThWKlU2EYLm4MB7ZeMwF+SFJutldYODXF6jzc6YEOC+VfX0SZQPqA=="], + + "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-3ZeLue5V82dT92CNL6rsal6I2weKw1cYu+rGKm8fOCCtJTR2gYeUfY3FqUnIJsMUPIH68oS5jmZ0NiJ508YpEw=="], + + "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.4", "", { "os": "win32", "cpu": "x64" }, "sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig=="], + + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="], + + "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], + + "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], + + "@jridgewell/set-array": ["@jridgewell/set-array@1.2.1", "", {}, "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="], + + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + + "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="], + + "@jsdoc/salty": ["@jsdoc/salty@0.2.9", "", { "dependencies": { "lodash": "^4.17.21" } }, "sha512-yYxMVH7Dqw6nO0d5NIV8OQWnitU8k6vXH8NtgqAfIa/IUqRMxRv/NUJJ08VEKbAakwxlgBl5PJdrU0dMPStsnw=="], + + "@minko-fe/lodash-pro": ["@minko-fe/lodash-pro@0.3.3", "", { "dependencies": { "@types/lodash-es": "^4.17.9", "deepmerge": "^4.3.1", "defu": "^6.1.4", "destr": "^2.0.3", "lodash-es": "^4.17.21", "p-is-promise": "^4.0.0" } }, "sha512-vK9JXI0THoB4myxhJAahqjP84PCmzdaXJgnb1+NfxLEAHClqPrOnUY2rh5RqU1+BAfsFaj3F4ErVw3h1kzzWeA=="], + + "@minko-fe/postcss-pxtoviewport": ["@minko-fe/postcss-pxtoviewport@1.5.0", "", { "dependencies": { "@minko-fe/lodash-pro": "^0.3.0", "decode-uri-component": "^0.4.1", "split-on-first": "^3.0.0" }, "peerDependencies": { "postcss": ">=8.0.0" } }, "sha512-sAI9nf4QujIZAAX2l/Lmxk6PACTf2HvW4hkKNzHjmHcObdkUZsxdCgxwb8aUPCu6oucpoeINiz3o7mm2eK1DxA=="], + + "@next/env": ["@next/env@16.0.1", "", {}, "sha512-LFvlK0TG2L3fEOX77OC35KowL8D7DlFF45C0OvKMC4hy8c/md1RC4UMNDlUGJqfCoCS2VWrZ4dSE6OjaX5+8mw=="], + + "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.0.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-R0YxRp6/4W7yG1nKbfu41bp3d96a0EalonQXiMe+1H9GTHfKxGNCGFNWUho18avRBPsO8T3RmdWuzmfurlQPbg=="], + + "@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.0.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-kETZBocRux3xITiZtOtVoVvXyQLB7VBxN7L6EPqgI5paZiUlnsgYv4q8diTNYeHmF9EiehydOBo20lTttCbHAg=="], + + "@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.0.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-hWg3BtsxQuSKhfe0LunJoqxjO4NEpBmKkE+P2Sroos7yB//OOX3jD5ISP2wv8QdUwtRehMdwYz6VB50mY6hqAg=="], + + "@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.0.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-UPnOvYg+fjAhP3b1iQStcYPWeBFRLrugEyK/lDKGk7kLNua8t5/DvDbAEFotfV1YfcOY6bru76qN9qnjLoyHCQ=="], + + "@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.0.1", "", { "os": "linux", "cpu": "x64" }, "sha512-Et81SdWkcRqAJziIgFtsFyJizHoWne4fzJkvjd6V4wEkWTB4MX6J0uByUb0peiJQ4WeAt6GGmMszE5KrXK6WKg=="], + + "@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.0.1", "", { "os": "linux", "cpu": "x64" }, "sha512-qBbgYEBRrC1egcG03FZaVfVxrJm8wBl7vr8UFKplnxNRprctdP26xEv9nJ07Ggq4y1adwa0nz2mz83CELY7N6Q=="], + + "@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.0.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-cPuBjYP6I699/RdbHJonb3BiRNEDm5CKEBuJ6SD8k3oLam2fDRMKAvmrli4QMDgT2ixyRJ0+DTkiODbIQhRkeQ=="], + + "@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.0.1", "", { "os": "win32", "cpu": "x64" }, "sha512-XeEUJsE4JYtfrXe/LaJn3z1pD19fK0Q6Er8Qoufi+HqvdO4LEPyCxLUt4rxA+4RfYo6S9gMlmzCMU2F+AatFqQ=="], + + "@protobufjs/aspromise": ["@protobufjs/aspromise@1.1.2", "", {}, "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="], + + "@protobufjs/base64": ["@protobufjs/base64@1.1.2", "", {}, "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="], + + "@protobufjs/codegen": ["@protobufjs/codegen@2.0.4", "", {}, "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="], + + "@protobufjs/eventemitter": ["@protobufjs/eventemitter@1.1.0", "", {}, "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="], + + "@protobufjs/fetch": ["@protobufjs/fetch@1.1.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" } }, "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ=="], + + "@protobufjs/float": ["@protobufjs/float@1.0.2", "", {}, "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="], + + "@protobufjs/inquire": ["@protobufjs/inquire@1.1.0", "", {}, "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="], + + "@protobufjs/path": ["@protobufjs/path@1.1.2", "", {}, "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="], + + "@protobufjs/pool": ["@protobufjs/pool@1.1.0", "", {}, "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="], + + "@protobufjs/utf8": ["@protobufjs/utf8@1.1.0", "", {}, "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="], + + "@radix-ui/number": ["@radix-ui/number@1.1.1", "", {}, "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g=="], + + "@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="], + + "@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w=="], + + "@radix-ui/react-avatar": ["@radix-ui/react-avatar@1.1.10", "", { "dependencies": { "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-is-hydrated": "0.1.0", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog=="], + + "@radix-ui/react-checkbox": ["@radix-ui/react-checkbox@1.3.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw=="], + + "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw=="], + + "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="], + + "@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="], + + "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw=="], + + "@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw=="], + + "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg=="], + + "@radix-ui/react-dropdown-menu": ["@radix-ui/react-dropdown-menu@2.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw=="], + + "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw=="], + + "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="], + + "@radix-ui/react-id": ["@radix-ui/react-id@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg=="], + + "@radix-ui/react-label": ["@radix-ui/react-label@2.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ=="], + + "@radix-ui/react-menu": ["@radix-ui/react-menu@2.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg=="], + + "@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA=="], + + "@radix-ui/react-popper": ["@radix-ui/react-popper@1.2.8", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-rect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw=="], + + "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ=="], + + "@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.5", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ=="], + + "@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="], + + "@radix-ui/react-progress": ["@radix-ui/react-progress@1.1.7", "", { "dependencies": { "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg=="], + + "@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA=="], + + "@radix-ui/react-select": ["@radix-ui/react-select@2.2.6", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ=="], + + "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + + "@radix-ui/react-switch": ["@radix-ui/react-switch@1.2.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ=="], + + "@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A=="], + + "@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.2.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg=="], + + "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="], + + "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="], + + "@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA=="], + + "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.1", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g=="], + + "@radix-ui/react-use-is-hydrated": ["@radix-ui/react-use-is-hydrated@0.1.0", "", { "dependencies": { "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA=="], + + "@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ=="], + + "@radix-ui/react-use-previous": ["@radix-ui/react-use-previous@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ=="], + + "@radix-ui/react-use-rect": ["@radix-ui/react-use-rect@1.1.1", "", { "dependencies": { "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w=="], + + "@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ=="], + + "@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.3", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug=="], + + "@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="], + + "@reduxjs/toolkit": ["@reduxjs/toolkit@2.9.2", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@standard-schema/utils": "^0.3.0", "immer": "^10.0.3", "redux": "^5.0.1", "redux-thunk": "^3.1.0", "reselect": "^5.1.0" }, "peerDependencies": { "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" }, "optionalPeers": ["react", "react-redux"] }, "sha512-ZAYu/NXkl/OhqTz7rfPaAhY0+e8Fr15jqNxte/2exKUxvHyQ/hcqmdekiN1f+Lcw3pE+34FCgX+26zcUE3duCg=="], + + "@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="], + + "@standard-schema/utils": ["@standard-schema/utils@0.3.0", "", {}, "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g=="], + + "@svgr/babel-plugin-add-jsx-attribute": ["@svgr/babel-plugin-add-jsx-attribute@8.0.0", "", { "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g=="], + + "@svgr/babel-plugin-remove-jsx-attribute": ["@svgr/babel-plugin-remove-jsx-attribute@8.0.0", "", { "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA=="], + + "@svgr/babel-plugin-remove-jsx-empty-expression": ["@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0", "", { "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA=="], + + "@svgr/babel-plugin-replace-jsx-attribute-value": ["@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0", "", { "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ=="], + + "@svgr/babel-plugin-svg-dynamic-title": ["@svgr/babel-plugin-svg-dynamic-title@8.0.0", "", { "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og=="], + + "@svgr/babel-plugin-svg-em-dimensions": ["@svgr/babel-plugin-svg-em-dimensions@8.0.0", "", { "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g=="], + + "@svgr/babel-plugin-transform-react-native-svg": ["@svgr/babel-plugin-transform-react-native-svg@8.1.0", "", { "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q=="], + + "@svgr/babel-plugin-transform-svg-component": ["@svgr/babel-plugin-transform-svg-component@8.0.0", "", { "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw=="], + + "@svgr/babel-preset": ["@svgr/babel-preset@8.1.0", "", { "dependencies": { "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", "@svgr/babel-plugin-transform-svg-component": "8.0.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug=="], + + "@svgr/core": ["@svgr/core@8.1.0", "", { "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", "camelcase": "^6.2.0", "cosmiconfig": "^8.1.3", "snake-case": "^3.0.4" } }, "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA=="], + + "@svgr/hast-util-to-babel-ast": ["@svgr/hast-util-to-babel-ast@8.0.0", "", { "dependencies": { "@babel/types": "^7.21.3", "entities": "^4.4.0" } }, "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q=="], + + "@svgr/plugin-jsx": ["@svgr/plugin-jsx@8.1.0", "", { "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", "@svgr/hast-util-to-babel-ast": "8.0.0", "svg-parser": "^2.0.4" }, "peerDependencies": { "@svgr/core": "*" } }, "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA=="], + + "@svgr/plugin-svgo": ["@svgr/plugin-svgo@8.1.0", "", { "dependencies": { "cosmiconfig": "^8.1.3", "deepmerge": "^4.3.1", "svgo": "^3.0.2" }, "peerDependencies": { "@svgr/core": "*" } }, "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA=="], + + "@svgr/webpack": ["@svgr/webpack@8.1.0", "", { "dependencies": { "@babel/core": "^7.21.3", "@babel/plugin-transform-react-constant-elements": "^7.21.3", "@babel/preset-env": "^7.20.2", "@babel/preset-react": "^7.18.6", "@babel/preset-typescript": "^7.21.0", "@svgr/core": "8.1.0", "@svgr/plugin-jsx": "8.1.0", "@svgr/plugin-svgo": "8.1.0" } }, "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA=="], + + "@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="], + + "@tailwindcss/node": ["@tailwindcss/node@4.1.16", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.19", "source-map-js": "^1.2.1", "tailwindcss": "4.1.16" } }, "sha512-BX5iaSsloNuvKNHRN3k2RcCuTEgASTo77mofW0vmeHkfrDWaoFAFvNHpEgtu0eqyypcyiBkDWzSMxJhp3AUVcw=="], + + "@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.16", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.16", "@tailwindcss/oxide-darwin-arm64": "4.1.16", "@tailwindcss/oxide-darwin-x64": "4.1.16", "@tailwindcss/oxide-freebsd-x64": "4.1.16", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.16", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.16", "@tailwindcss/oxide-linux-arm64-musl": "4.1.16", "@tailwindcss/oxide-linux-x64-gnu": "4.1.16", "@tailwindcss/oxide-linux-x64-musl": "4.1.16", "@tailwindcss/oxide-wasm32-wasi": "4.1.16", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.16", "@tailwindcss/oxide-win32-x64-msvc": "4.1.16" } }, "sha512-2OSv52FRuhdlgyOQqgtQHuCgXnS8nFSYRp2tJ+4WZXKgTxqPy7SMSls8c3mPT5pkZ17SBToGM5LHEJBO7miEdg=="], + + "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.16", "", { "os": "android", "cpu": "arm64" }, "sha512-8+ctzkjHgwDJ5caq9IqRSgsP70xhdhJvm+oueS/yhD5ixLhqTw9fSL1OurzMUhBwE5zK26FXLCz2f/RtkISqHA=="], + + "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.16", "", { "os": "darwin", "cpu": "arm64" }, "sha512-C3oZy5042v2FOALBZtY0JTDnGNdS6w7DxL/odvSny17ORUnaRKhyTse8xYi3yKGyfnTUOdavRCdmc8QqJYwFKA=="], + + "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.16", "", { "os": "darwin", "cpu": "x64" }, "sha512-vjrl/1Ub9+JwU6BP0emgipGjowzYZMjbWCDqwA2Z4vCa+HBSpP4v6U2ddejcHsolsYxwL5r4bPNoamlV0xDdLg=="], + + "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.16", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TSMpPYpQLm+aR1wW5rKuUuEruc/oOX3C7H0BTnPDn7W/eMw8W+MRMpiypKMkXZfwH8wqPIRKppuZoedTtNj2tg=="], + + "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.16", "", { "os": "linux", "cpu": "arm" }, "sha512-p0GGfRg/w0sdsFKBjMYvvKIiKy/LNWLWgV/plR4lUgrsxFAoQBFrXkZ4C0w8IOXfslB9vHK/JGASWD2IefIpvw=="], + + "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.16", "", { "os": "linux", "cpu": "arm64" }, "sha512-DoixyMmTNO19rwRPdqviTrG1rYzpxgyYJl8RgQvdAQUzxC1ToLRqtNJpU/ATURSKgIg6uerPw2feW0aS8SNr/w=="], + + "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.16", "", { "os": "linux", "cpu": "arm64" }, "sha512-H81UXMa9hJhWhaAUca6bU2wm5RRFpuHImrwXBUvPbYb+3jo32I9VIwpOX6hms0fPmA6f2pGVlybO6qU8pF4fzQ=="], + + "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.16", "", { "os": "linux", "cpu": "x64" }, "sha512-ZGHQxDtFC2/ruo7t99Qo2TTIvOERULPl5l0K1g0oK6b5PGqjYMga+FcY1wIUnrUxY56h28FxybtDEla+ICOyew=="], + + "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.16", "", { "os": "linux", "cpu": "x64" }, "sha512-Oi1tAaa0rcKf1Og9MzKeINZzMLPbhxvm7rno5/zuP1WYmpiG0bEHq4AcRUiG2165/WUzvxkW4XDYCscZWbTLZw=="], + + "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.16", "", { "dependencies": { "@emnapi/core": "^1.5.0", "@emnapi/runtime": "^1.5.0", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.0.7", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.4.0" }, "cpu": "none" }, "sha512-B01u/b8LteGRwucIBmCQ07FVXLzImWESAIMcUU6nvFt/tYsQ6IHz8DmZ5KtvmwxD+iTYBtM1xwoGXswnlu9v0Q=="], + + "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.16", "", { "os": "win32", "cpu": "arm64" }, "sha512-zX+Q8sSkGj6HKRTMJXuPvOcP8XfYON24zJBRPlszcH1Np7xuHXhWn8qfFjIujVzvH3BHU+16jBXwgpl20i+v9A=="], + + "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.16", "", { "os": "win32", "cpu": "x64" }, "sha512-m5dDFJUEejbFqP+UXVstd4W/wnxA4F61q8SoL+mqTypId2T2ZpuxosNSgowiCnLp2+Z+rivdU0AqpfgiD7yCBg=="], + + "@tailwindcss/postcss": ["@tailwindcss/postcss@4.1.16", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.1.16", "@tailwindcss/oxide": "4.1.16", "postcss": "^8.4.41", "tailwindcss": "4.1.16" } }, "sha512-Qn3SFGPXYQMKR/UtqS+dqvPrzEeBZHrFA92maT4zijCVggdsXnDBMsPFJo1eArX3J+O+Gi+8pV4PkqjLCNBk3A=="], + + "@trulience/react-sdk": ["@trulience/react-sdk@1.0.98", "", { "peerDependencies": { "react": ">=16.11.0", "react-dom": ">=16.11.0" } }, "sha512-8ZNdYyATwXl5idwzyfpF7CWWPY1AmhweZzDy1XDdLsHKjyFmStZpDBhYyTvr/h/rDHahT+rBCkYJhgt42MkT+w=="], + + "@trysound/sax": ["@trysound/sax@0.2.0", "", {}, "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA=="], + + "@types/hoist-non-react-statics": ["@types/hoist-non-react-statics@3.3.6", "", { "dependencies": { "@types/react": "*", "hoist-non-react-statics": "^3.3.0" } }, "sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw=="], + + "@types/linkify-it": ["@types/linkify-it@5.0.0", "", {}, "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q=="], + + "@types/lodash": ["@types/lodash@4.17.18", "", {}, "sha512-KJ65INaxqxmU6EoCiJmRPZC9H9RVWCRd349tXM2M3O5NA7cY6YL7c0bHAHQ93NOfTObEQ004kd2QVHs/r0+m4g=="], + + "@types/lodash-es": ["@types/lodash-es@4.17.12", "", { "dependencies": { "@types/lodash": "*" } }, "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ=="], + + "@types/markdown-it": ["@types/markdown-it@14.1.2", "", { "dependencies": { "@types/linkify-it": "^5", "@types/mdurl": "^2" } }, "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog=="], + + "@types/mdurl": ["@types/mdurl@2.0.0", "", {}, "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg=="], + + "@types/node": ["@types/node@20.19.24", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-FE5u0ezmi6y9OZEzlJfg37mqqf6ZDSF2V/NLjUyGrR9uTZ7Sb9F7bLNZ03S4XVUNRWGA7Ck4c1kK+YnuWjl+DA=="], + + "@types/react": ["@types/react@19.2.2", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA=="], + + "@types/react-dom": ["@types/react-dom@19.2.2", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw=="], + + "@types/react-redux": ["@types/react-redux@7.1.34", "", { "dependencies": { "@types/hoist-non-react-statics": "^3.3.0", "@types/react": "*", "hoist-non-react-statics": "^3.3.0", "redux": "^4.0.0" } }, "sha512-GdFaVjEbYv4Fthm2ZLvj1VSCedV7TqE5y1kNwnjSdBOTXuRSgowux6J8TAct15T3CKBr63UMk+2CO7ilRhyrAQ=="], + + "@types/use-sync-external-store": ["@types/use-sync-external-store@0.0.6", "", {}, "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg=="], + + "acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], + + "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], + + "agora-rtc-sdk-ng": ["agora-rtc-sdk-ng@4.24.0", "", { "dependencies": { "@agora-js/media": "4.24.0", "@agora-js/report": "4.24.0", "@agora-js/shared": "4.24.0", "agora-rte-extension": "^1.2.4", "axios": "^1.8.3", "formdata-polyfill": "^4.0.7", "pako": "^2.1.0", "ua-parser-js": "^0.7.34", "webrtc-adapter": "8.2.0" } }, "sha512-2apG/07EtsuX21ncSF77q+dr6/kDgu9B/RpKtstCtaq46l4/Eraoecewi4zXRUCY3Im+8dzTIXx6jUwyPdxdHQ=="], + + "agora-rte-extension": ["agora-rte-extension@1.2.4", "", {}, "sha512-0ovZz1lbe30QraG1cU+ji7EnQ8aUu+Hf3F+a8xPml3wPOyUQEK6CTdxV9kMecr9t+fIDrGeW7wgJTsM1DQE7Nw=="], + + "agora-rtm": ["agora-rtm@2.2.3", "", { "peerDependencies": { "agora-rtc-sdk-ng": "4.23.0" } }, "sha512-5O6uINrtnNDXijZEAmTwLzC1J6GizQoRb4moRx+DsVeYjcEbMjZAFcSnZVYHsjq3LrWetdknMhGt2o0zZJEBtQ=="], + + "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], + + "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="], + + "asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="], + + "axios": ["axios@1.13.1", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-hU4EGxxt+j7TQijx1oYdAjw4xuIp1wRQSsbMFwSthCWeBQur1eF+qJ5iQ5sN3Tw8YRzQNKb8jszgBdMDVqwJcw=="], + + "babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.13", "", { "dependencies": { "@babel/compat-data": "^7.22.6", "@babel/helper-define-polyfill-provider": "^0.6.4", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g=="], + + "babel-plugin-polyfill-corejs3": ["babel-plugin-polyfill-corejs3@0.11.1", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.3", "core-js-compat": "^3.40.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ=="], + + "babel-plugin-polyfill-regenerator": ["babel-plugin-polyfill-regenerator@0.6.4", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.4" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw=="], + + "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + + "bluebird": ["bluebird@3.7.2", "", {}, "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="], + + "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], + + "brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + + "browserslist": ["browserslist@4.25.0", "", { "dependencies": { "caniuse-lite": "^1.0.30001718", "electron-to-chromium": "^1.5.160", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA=="], + + "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], + + "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], + + "camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="], + + "caniuse-lite": ["caniuse-lite@1.0.30001724", "", {}, "sha512-WqJo7p0TbHDOythNTqYujmaJTvtYRZrjpP8TCvH6Vb9CYJerJNKamKzIWOM4BkQatWj9H2lYulpdAQNBe7QhNA=="], + + "catharsis": ["catharsis@0.9.0", "", { "dependencies": { "lodash": "^4.17.15" } }, "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A=="], + + "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + + "class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="], + + "client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="], + + "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], + + "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + + "combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="], + + "commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="], + + "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], + + "core-js-compat": ["core-js-compat@3.43.0", "", { "dependencies": { "browserslist": "^4.25.0" } }, "sha512-2GML2ZsCc5LR7hZYz4AXmjQw8zuy2T//2QntwdnpuYI7jteT6GVYJL7F6C2C57R7gSYrcqVW3lAALefdbhBLDA=="], + + "cosmiconfig": ["cosmiconfig@8.3.6", "", { "dependencies": { "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0", "path-type": "^4.0.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA=="], + + "css-select": ["css-select@5.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg=="], + + "css-tree": ["css-tree@2.3.1", "", { "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" } }, "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw=="], + + "css-what": ["css-what@6.1.0", "", {}, "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw=="], + + "csso": ["csso@5.0.5", "", { "dependencies": { "css-tree": "~2.2.0" } }, "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ=="], + + "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="], + + "debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="], + + "decode-uri-component": ["decode-uri-component@0.4.1", "", {}, "sha512-+8VxcR21HhTy8nOt6jf20w0c9CADrw1O8d+VZ/YzzCt4bJ3uBjw+D1q2osAB8RnpwwaeYBxy0HyKQxD5JBMuuQ=="], + + "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], + + "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], + + "defu": ["defu@6.1.4", "", {}, "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="], + + "delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="], + + "destr": ["destr@2.0.5", "", {}, "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA=="], + + "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + + "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="], + + "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="], + + "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="], + + "domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="], + + "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="], + + "dot-case": ["dot-case@3.0.4", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w=="], + + "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], + + "electron-to-chromium": ["electron-to-chromium@1.5.172", "", {}, "sha512-fnKW9dGgmBfsebbYognQSv0CGGLFH1a5iV9EDYTBwmAQn+whbzHbLFlC+3XbHc8xaNtpO0etm8LOcRXs1qMRkQ=="], + + "enhanced-resolve": ["enhanced-resolve@5.18.3", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww=="], + + "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + + "error-ex": ["error-ex@1.3.2", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g=="], + + "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], + + "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], + + "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="], + + "es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="], + + "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + + "escape-string-regexp": ["escape-string-regexp@2.0.0", "", {}, "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w=="], + + "escodegen": ["escodegen@1.14.3", "", { "dependencies": { "esprima": "^4.0.1", "estraverse": "^4.2.0", "esutils": "^2.0.2", "optionator": "^0.8.1" }, "optionalDependencies": { "source-map": "~0.6.1" }, "bin": { "esgenerate": "bin/esgenerate.js", "escodegen": "bin/escodegen.js" } }, "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw=="], + + "eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], + + "espree": ["espree@9.6.1", "", { "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" } }, "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ=="], + + "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="], + + "estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="], + + "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], + + "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="], + + "fetch-blob": ["fetch-blob@3.2.0", "", { "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" } }, "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ=="], + + "follow-redirects": ["follow-redirects@1.15.9", "", {}, "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ=="], + + "form-data": ["form-data@4.0.4", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow=="], + + "formdata-polyfill": ["formdata-polyfill@4.0.10", "", { "dependencies": { "fetch-blob": "^3.1.2" } }, "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g=="], + + "framer-motion": ["framer-motion@12.23.26", "", { "dependencies": { "motion-dom": "^12.23.23", "motion-utils": "^12.23.6", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-cPcIhgR42xBn1Uj+PzOyheMtZ73H927+uWPDVhUMqxy8UHt6Okavb6xIz9J/phFUHUj0OncR6UvMfJTXoc/LKA=="], + + "fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="], + + "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], + + "gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="], + + "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="], + + "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="], + + "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], + + "glob": ["glob@8.1.0", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^5.0.1", "once": "^1.3.0" } }, "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ=="], + + "globals": ["globals@11.12.0", "", {}, "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="], + + "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], + + "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + + "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], + + "has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="], + + "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], + + "hoist-non-react-statics": ["hoist-non-react-statics@3.3.2", "", { "dependencies": { "react-is": "^16.7.0" } }, "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw=="], + + "immer": ["immer@10.1.1", "", {}, "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw=="], + + "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], + + "inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="], + + "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], + + "is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="], + + "is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="], + + "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], + + "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + + "js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], + + "js2xmlparser": ["js2xmlparser@4.0.2", "", { "dependencies": { "xmlcreate": "^2.0.4" } }, "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA=="], + + "jsdoc": ["jsdoc@4.0.4", "", { "dependencies": { "@babel/parser": "^7.20.15", "@jsdoc/salty": "^0.2.1", "@types/markdown-it": "^14.1.1", "bluebird": "^3.7.2", "catharsis": "^0.9.0", "escape-string-regexp": "^2.0.0", "js2xmlparser": "^4.0.2", "klaw": "^3.0.0", "markdown-it": "^14.1.0", "markdown-it-anchor": "^8.6.7", "marked": "^4.0.10", "mkdirp": "^1.0.4", "requizzle": "^0.2.3", "strip-json-comments": "^3.1.0", "underscore": "~1.13.2" }, "bin": { "jsdoc": "./jsdoc.js" } }, "sha512-zeFezwyXeG4syyYHbvh1A967IAqq/67yXtXvuL5wnqCkFZe8I0vKfm+EO+YEvLguo6w9CDUbrAXVtJSHh2E8rw=="], + + "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="], + + "json-parse-even-better-errors": ["json-parse-even-better-errors@2.3.1", "", {}, "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="], + + "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], + + "klaw": ["klaw@3.0.0", "", { "dependencies": { "graceful-fs": "^4.1.9" } }, "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g=="], + + "levn": ["levn@0.3.0", "", { "dependencies": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" } }, "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA=="], + + "lightningcss": ["lightningcss@1.30.2", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.30.2", "lightningcss-darwin-arm64": "1.30.2", "lightningcss-darwin-x64": "1.30.2", "lightningcss-freebsd-x64": "1.30.2", "lightningcss-linux-arm-gnueabihf": "1.30.2", "lightningcss-linux-arm64-gnu": "1.30.2", "lightningcss-linux-arm64-musl": "1.30.2", "lightningcss-linux-x64-gnu": "1.30.2", "lightningcss-linux-x64-musl": "1.30.2", "lightningcss-win32-arm64-msvc": "1.30.2", "lightningcss-win32-x64-msvc": "1.30.2" } }, "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ=="], + + "lightningcss-android-arm64": ["lightningcss-android-arm64@1.30.2", "", { "os": "android", "cpu": "arm64" }, "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A=="], + + "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA=="], + + "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ=="], + + "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA=="], + + "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.2", "", { "os": "linux", "cpu": "arm" }, "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA=="], + + "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A=="], + + "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA=="], + + "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w=="], + + "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA=="], + + "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ=="], + + "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw=="], + + "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], + + "linkify-it": ["linkify-it@5.0.0", "", { "dependencies": { "uc.micro": "^2.0.0" } }, "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ=="], + + "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="], + + "lodash-es": ["lodash-es@4.17.21", "", {}, "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="], + + "lodash.debounce": ["lodash.debounce@4.0.8", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="], + + "long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="], + + "lower-case": ["lower-case@2.0.2", "", { "dependencies": { "tslib": "^2.0.3" } }, "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg=="], + + "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], + + "lucide-react": ["lucide-react@0.546.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Z94u6fKT43lKeYHiVyvyR8fT7pwCzDu7RyMPpTvh054+xahSgj4HFQ+NmflvzdXsoAjYGdCguGaFKYuvq0ThCQ=="], + + "magic-string": ["magic-string@0.30.19", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw=="], + + "markdown-it": ["markdown-it@14.1.0", "", { "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", "linkify-it": "^5.0.0", "mdurl": "^2.0.0", "punycode.js": "^2.3.1", "uc.micro": "^2.1.0" }, "bin": { "markdown-it": "bin/markdown-it.mjs" } }, "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg=="], + + "markdown-it-anchor": ["markdown-it-anchor@8.6.7", "", { "peerDependencies": { "@types/markdown-it": "*", "markdown-it": "*" } }, "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA=="], + + "marked": ["marked@4.3.0", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A=="], + + "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], + + "mdn-data": ["mdn-data@2.0.30", "", {}, "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA=="], + + "mdurl": ["mdurl@2.0.0", "", {}, "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w=="], + + "mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + + "mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], + + "minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="], + + "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], + + "mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="], + + "motion-dom": ["motion-dom@12.23.23", "", { "dependencies": { "motion-utils": "^12.23.6" } }, "sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA=="], + + "motion-utils": ["motion-utils@12.23.6", "", {}, "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + + "next": ["next@16.0.1", "", { "dependencies": { "@next/env": "16.0.1", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.0.1", "@next/swc-darwin-x64": "16.0.1", "@next/swc-linux-arm64-gnu": "16.0.1", "@next/swc-linux-arm64-musl": "16.0.1", "@next/swc-linux-x64-gnu": "16.0.1", "@next/swc-linux-x64-musl": "16.0.1", "@next/swc-win32-arm64-msvc": "16.0.1", "@next/swc-win32-x64-msvc": "16.0.1", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-e9RLSssZwd35p7/vOa+hoDFggUZIUbZhIUSLZuETCwrCVvxOs87NamoUzT+vbcNAL8Ld9GobBnWOA6SbV/arOw=="], + + "next-themes": ["next-themes@0.4.6", "", { "peerDependencies": { "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA=="], + + "no-case": ["no-case@3.0.4", "", { "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" } }, "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg=="], + + "node-domexception": ["node-domexception@1.0.0", "", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="], + + "node-releases": ["node-releases@2.0.19", "", {}, "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw=="], + + "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="], + + "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], + + "optionator": ["optionator@0.8.3", "", { "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" } }, "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA=="], + + "p-is-promise": ["p-is-promise@4.0.0", "", {}, "sha512-4G3B+86qsIAX/+ip/yhHX9WUcyFKYkQYtE5bGkjpZyGK0Re53RbHky2UKt6RQVkDbUXb8EJRb4iga2SaI360nQ=="], + + "pako": ["pako@2.1.0", "", {}, "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="], + + "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], + + "parse-json": ["parse-json@5.2.0", "", { "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" } }, "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg=="], + + "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], + + "path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], + + "prelude-ls": ["prelude-ls@1.1.2", "", {}, "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w=="], + + "protobufjs": ["protobufjs@7.5.4", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg=="], + + "protobufjs-cli": ["protobufjs-cli@1.1.3", "", { "dependencies": { "chalk": "^4.0.0", "escodegen": "^1.13.0", "espree": "^9.0.0", "estraverse": "^5.1.0", "glob": "^8.0.0", "jsdoc": "^4.0.0", "minimist": "^1.2.0", "semver": "^7.1.2", "tmp": "^0.2.1", "uglify-js": "^3.7.7" }, "peerDependencies": { "protobufjs": "^7.0.0" }, "bin": { "pbjs": "bin/pbjs", "pbts": "bin/pbts" } }, "sha512-MqD10lqF+FMsOayFiNOdOGNlXc4iKDCf0ZQPkPR+gizYh9gqUeGTWulABUCdI+N67w5RfJ6xhgX4J8pa8qmMXQ=="], + + "proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="], + + "punycode.js": ["punycode.js@2.3.1", "", {}, "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA=="], + + "react": ["react@19.2.0", "", {}, "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ=="], + + "react-colorful": ["react-colorful@5.6.1", "", { "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw=="], + + "react-dom": ["react-dom@19.2.0", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.0" } }, "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ=="], + + "react-hook-form": ["react-hook-form@7.65.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "sha512-xtOzDz063WcXvGWaHgLNrNzlsdFgtUWcb32E6WFaGTd7kPZG3EeDusjdZfUsPwKCKVXy1ZlntifaHZ4l8pAsmw=="], + + "react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], + + "react-redux": ["react-redux@9.2.0", "", { "dependencies": { "@types/use-sync-external-store": "^0.0.6", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { "@types/react": "^18.2.25 || ^19", "react": "^18.0 || ^19", "redux": "^5.0.0" }, "optionalPeers": ["@types/react", "redux"] }, "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g=="], + + "react-remove-scroll": ["react-remove-scroll@2.7.1", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA=="], + + "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="], + + "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="], + + "redux": ["redux@5.0.1", "", {}, "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w=="], + + "redux-thunk": ["redux-thunk@3.1.0", "", { "peerDependencies": { "redux": "^5.0.0" } }, "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw=="], + + "regenerate": ["regenerate@1.4.2", "", {}, "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A=="], + + "regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.0", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA=="], + + "regexpu-core": ["regexpu-core@6.2.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.0", "regjsgen": "^0.8.0", "regjsparser": "^0.12.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" } }, "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA=="], + + "regjsgen": ["regjsgen@0.8.0", "", {}, "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q=="], + + "regjsparser": ["regjsparser@0.12.0", "", { "dependencies": { "jsesc": "~3.0.2" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ=="], + + "requizzle": ["requizzle@0.2.4", "", { "dependencies": { "lodash": "^4.17.21" } }, "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw=="], + + "reselect": ["reselect@5.1.1", "", {}, "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w=="], + + "resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="], + + "resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], + + "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], + + "sdp": ["sdp@3.2.1", "", {}, "sha512-lwsAIzOPlH8/7IIjjz3K0zYBk7aBVVcvjMwt3M4fLxpjMYyy7i3I97SLHebgn4YBjirkzfp3RvRDWSKsh/+WFw=="], + + "semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="], + + "sharp": ["sharp@0.34.4", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.0", "semver": "^7.7.2" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.4", "@img/sharp-darwin-x64": "0.34.4", "@img/sharp-libvips-darwin-arm64": "1.2.3", "@img/sharp-libvips-darwin-x64": "1.2.3", "@img/sharp-libvips-linux-arm": "1.2.3", "@img/sharp-libvips-linux-arm64": "1.2.3", "@img/sharp-libvips-linux-ppc64": "1.2.3", "@img/sharp-libvips-linux-s390x": "1.2.3", "@img/sharp-libvips-linux-x64": "1.2.3", "@img/sharp-libvips-linuxmusl-arm64": "1.2.3", "@img/sharp-libvips-linuxmusl-x64": "1.2.3", "@img/sharp-linux-arm": "0.34.4", "@img/sharp-linux-arm64": "0.34.4", "@img/sharp-linux-ppc64": "0.34.4", "@img/sharp-linux-s390x": "0.34.4", "@img/sharp-linux-x64": "0.34.4", "@img/sharp-linuxmusl-arm64": "0.34.4", "@img/sharp-linuxmusl-x64": "0.34.4", "@img/sharp-wasm32": "0.34.4", "@img/sharp-win32-arm64": "0.34.4", "@img/sharp-win32-ia32": "0.34.4", "@img/sharp-win32-x64": "0.34.4" } }, "sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA=="], + + "snake-case": ["snake-case@3.0.4", "", { "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg=="], + + "sonner": ["sonner@1.7.4", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-DIS8z4PfJRbIyfVFDVnK9rO3eYDtse4Omcm6bt0oEr5/jtLgysmjuBl1frJ9E/EQZrFmKx2A8m/s5s9CRXIzhw=="], + + "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + + "split-on-first": ["split-on-first@3.0.0", "", {}, "sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA=="], + + "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], + + "styled-jsx": ["styled-jsx@5.1.6", "", { "dependencies": { "client-only": "0.0.1" }, "peerDependencies": { "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" } }, "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA=="], + + "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + + "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], + + "svg-parser": ["svg-parser@2.0.4", "", {}, "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ=="], + + "svgo": ["svgo@3.3.2", "", { "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", "css-select": "^5.1.0", "css-tree": "^2.3.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.0.0" }, "bin": "./bin/svgo" }, "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw=="], + + "tailwind-merge": ["tailwind-merge@2.6.0", "", {}, "sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA=="], + + "tailwindcss": ["tailwindcss@4.1.16", "", {}, "sha512-pONL5awpaQX4LN5eiv7moSiSPd/DLDzKVRJz8Q9PgzmAdd1R4307GQS2ZpfiN7ZmekdQrfhZZiSE5jkLR4WNaA=="], + + "tailwindcss-animate": ["tailwindcss-animate@1.0.7", "", { "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders" } }, "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA=="], + + "tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="], + + "tmp": ["tmp@0.2.3", "", {}, "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w=="], + + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + + "type-check": ["type-check@0.3.2", "", { "dependencies": { "prelude-ls": "~1.1.2" } }, "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg=="], + + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + + "ua-parser-js": ["ua-parser-js@0.7.40", "", { "bin": { "ua-parser-js": "script/cli.js" } }, "sha512-us1E3K+3jJppDBa3Tl0L3MOJiGhe1C6P0+nIvQAFYbxlMAx0h81eOwLmU57xgqToduDDPx3y5QsdjPfDu+FgOQ=="], + + "uc.micro": ["uc.micro@2.1.0", "", {}, "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A=="], + + "uglify-js": ["uglify-js@3.19.3", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ=="], + + "underscore": ["underscore@1.13.7", "", {}, "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g=="], + + "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + + "unicode-canonical-property-names-ecmascript": ["unicode-canonical-property-names-ecmascript@2.0.1", "", {}, "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg=="], + + "unicode-match-property-ecmascript": ["unicode-match-property-ecmascript@2.0.0", "", { "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" } }, "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q=="], + + "unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.0", "", {}, "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg=="], + + "unicode-property-aliases-ecmascript": ["unicode-property-aliases-ecmascript@2.1.0", "", {}, "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w=="], + + "update-browserslist-db": ["update-browserslist-db@1.1.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw=="], + + "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="], + + "use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="], + + "use-sync-external-store": ["use-sync-external-store@1.5.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A=="], + + "web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="], + + "webrtc-adapter": ["webrtc-adapter@8.2.0", "", { "dependencies": { "sdp": "^3.0.2" } }, "sha512-umxCMgedPAVq4Pe/jl3xmelLXLn4XZWFEMR5Iipb5wJ+k1xMX0yC4ZY9CueZUU1MjapFxai1tFGE7R/kotH6Ww=="], + + "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], + + "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], + + "xmlcreate": ["xmlcreate@2.0.4", "", {}, "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg=="], + + "yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], + + "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + + "@agora-js/media/axios": ["axios@1.12.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw=="], + + "@agora-js/report/axios": ["axios@1.12.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw=="], + + "@agora-js/shared/axios": ["axios@1.12.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw=="], + + "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@babel/helper-create-class-features-plugin/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@babel/helper-create-regexp-features-plugin/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@babel/preset-env/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@jridgewell/gen-mapping/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="], + + "@jridgewell/trace-mapping/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="], + + "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.5.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg=="], + + "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.5.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="], + + "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="], + + "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.0.7", "", { "dependencies": { "@emnapi/core": "^1.5.0", "@emnapi/runtime": "^1.5.0", "@tybys/wasm-util": "^0.10.1" }, "bundled": true }, "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw=="], + + "@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], + + "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + + "@types/react-redux/redux": ["redux@4.2.1", "", { "dependencies": { "@babel/runtime": "^7.9.2" } }, "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w=="], + + "agora-rtc-sdk-ng/axios": ["axios@1.12.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw=="], + + "babel-plugin-polyfill-corejs2/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "csso/css-tree": ["css-tree@2.2.1", "", { "dependencies": { "mdn-data": "2.0.28", "source-map-js": "^1.0.1" } }, "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA=="], + + "escodegen/estraverse": ["estraverse@4.3.0", "", {}, "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="], + + "next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="], + + "protobufjs/@types/node": ["@types/node@20.19.22", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-hRnu+5qggKDSyWHlnmThnUqg62l29Aj/6vcYgUaSFL9oc7DVjeWEQN3PRgdSc6F8d9QRMWkf36CLMch1Do/+RQ=="], + + "regjsparser/jsesc": ["jsesc@3.0.2", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g=="], + + "csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="], + } +} diff --git a/ai_agents/agents/examples/doodler/frontend/components.json b/ai_agents/agents/examples/doodler/frontend/components.json new file mode 100644 index 0000000000..c6a338228f --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "", + "css": "src/app/global.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "iconLibrary": "lucide" +} diff --git a/ai_agents/agents/examples/doodler/frontend/next-env.d.ts b/ai_agents/agents/examples/doodler/frontend/next-env.d.ts new file mode 100644 index 0000000000..c4b7818fbb --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/next-env.d.ts @@ -0,0 +1,6 @@ +/// +/// +import "./.next/dev/types/routes.d.ts"; + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/ai_agents/agents/examples/doodler/frontend/next.config.mjs b/ai_agents/agents/examples/doodler/frontend/next.config.mjs new file mode 100644 index 0000000000..539579f6b7 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/next.config.mjs @@ -0,0 +1,18 @@ +/** @type {import('next').NextConfig} */ + +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const nextConfig = { + // basePath: '/ai-agent', + // output: 'export', + output: "standalone", + reactStrictMode: false, + // this includes files from the monorepo base two directories up + outputFileTracingRoot: path.join(__dirname, "./"), +}; + +export default nextConfig; diff --git a/ai_agents/agents/examples/doodler/frontend/package-lock.json b/ai_agents/agents/examples/doodler/frontend/package-lock.json new file mode 100644 index 0000000000..204d0280c7 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/package-lock.json @@ -0,0 +1,6524 @@ +{ + "name": "ten_agent_playground", + "version": "0.6.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "ten_agent_playground", + "version": "0.6.0", + "dependencies": { + "@hookform/resolvers": "^3.10.0", + "@radix-ui/react-avatar": "^1.1.10", + "@radix-ui/react-checkbox": "^1.3.3", + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-dropdown-menu": "^2.1.16", + "@radix-ui/react-label": "^2.1.7", + "@radix-ui/react-popover": "^1.1.15", + "@radix-ui/react-progress": "^1.1.7", + "@radix-ui/react-select": "^2.2.6", + "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-switch": "^1.2.6", + "@radix-ui/react-tabs": "^1.1.13", + "@radix-ui/react-tooltip": "^1.2.8", + "@reduxjs/toolkit": "^2.9.2", + "@trulience/react-sdk": "^1.0.98", + "agora-rtc-sdk-ng": "^4.23.0", + "agora-rtm": "^2.2.3", + "axios": "^1.13.1", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "framer-motion": "^12.23.26", + "lucide-react": "^0.546.0", + "next": "16.0.1", + "next-themes": "^0.4.6", + "protobufjs": "^7.5.4", + "react": "19.2.0", + "react-colorful": "^5.6.1", + "react-dom": "19.2.0", + "react-hook-form": "^7.65.0", + "react-redux": "^9.2.0", + "redux": "^5.0.1", + "sonner": "^1.7.4", + "tailwind-merge": "^2.6.0", + "tailwindcss-animate": "^1.0.7", + "zod": "^3.25.76" + }, + "devDependencies": { + "@biomejs/biome": "2.1.4", + "@minko-fe/postcss-pxtoviewport": "^1.5.0", + "@svgr/webpack": "^8.1.0", + "@tailwindcss/postcss": "^4.1.16", + "@types/node": "^20.19.24", + "@types/react": "19.2.2", + "@types/react-dom": "19.2.2", + "@types/react-redux": "^7.1.34", + "postcss": "^8.5.6", + "protobufjs-cli": "^1.1.3", + "tailwindcss": "^4.1.16", + "typescript": "^5.9.3" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@agora-js/media": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/@agora-js/media/-/media-4.23.0.tgz", + "integrity": "sha512-rV0CGP5nhvd7XrzpCqN7Fud+W//c/+f0dMe7wPB+DS/ckeTVxSdg96cTfEJS9poeTdDUvfhHyi0iECLPfUjkKA==", + "dependencies": { + "@agora-js/report": "4.23.0", + "@agora-js/shared": "4.23.0", + "agora-rte-extension": "^1.2.4", + "axios": "^1.7.7", + "webrtc-adapter": "8.2.0" + } + }, + "node_modules/@agora-js/report": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/@agora-js/report/-/report-4.23.0.tgz", + "integrity": "sha512-ti2HZc8ITRgbmukHRa+ZlH4ecCByHdQpPVT6v3vIn+ihvqrxs3A871iLe1jbjbeGNuOwqcaznSoRXOVsREeq2A==", + "dependencies": { + "@agora-js/shared": "4.23.0", + "axios": "^1.7.7" + } + }, + "node_modules/@agora-js/shared": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/@agora-js/shared/-/shared-4.23.0.tgz", + "integrity": "sha512-gfcEJu/+vPvMKYcjyWqmQKo4d0r0yggl9AhktsTWjg6mhScv4Lt3B8JdGGXvlIP6R+horRHjxsqPCdCVs1N4/w==", + "dependencies": { + "axios": "^1.7.7", + "ua-parser-js": "^0.7.34" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "dev": true, + "license": "Apache-2.0", + "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.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.27.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.27.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.27.3", + "@babel/helpers": "^7.27.4", + "@babel/parser": "^7.27.4", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.27.4", + "@babel/types": "^7.27.3", + "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", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.27.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.5", + "@babel/types": "^7.27.3", + "@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.27.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "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/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.27.1", + "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", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "regexpu-core": "^6.2.0", + "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", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.4", + "dev": true, + "license": "MIT", + "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.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.27.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.1", + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.27.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.27.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "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.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "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.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.27.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/traverse": "^7.27.1", + "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.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/template": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.27.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.27.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.27.3", + "@babel/plugin-transform-parameters": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.27.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.27.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.27.1", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.27.1", + "@babel/plugin-syntax-import-attributes": "^7.27.1", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.27.1", + "@babel/plugin-transform-async-to-generator": "^7.27.1", + "@babel/plugin-transform-block-scoped-functions": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.27.1", + "@babel/plugin-transform-class-properties": "^7.27.1", + "@babel/plugin-transform-class-static-block": "^7.27.1", + "@babel/plugin-transform-classes": "^7.27.1", + "@babel/plugin-transform-computed-properties": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.27.1", + "@babel/plugin-transform-dotall-regex": "^7.27.1", + "@babel/plugin-transform-duplicate-keys": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-dynamic-import": "^7.27.1", + "@babel/plugin-transform-exponentiation-operator": "^7.27.1", + "@babel/plugin-transform-export-namespace-from": "^7.27.1", + "@babel/plugin-transform-for-of": "^7.27.1", + "@babel/plugin-transform-function-name": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.27.1", + "@babel/plugin-transform-literals": "^7.27.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.27.1", + "@babel/plugin-transform-member-expression-literals": "^7.27.1", + "@babel/plugin-transform-modules-amd": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-modules-systemjs": "^7.27.1", + "@babel/plugin-transform-modules-umd": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-new-target": "^7.27.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", + "@babel/plugin-transform-numeric-separator": "^7.27.1", + "@babel/plugin-transform-object-rest-spread": "^7.27.2", + "@babel/plugin-transform-object-super": "^7.27.1", + "@babel/plugin-transform-optional-catch-binding": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1", + "@babel/plugin-transform-parameters": "^7.27.1", + "@babel/plugin-transform-private-methods": "^7.27.1", + "@babel/plugin-transform-private-property-in-object": "^7.27.1", + "@babel/plugin-transform-property-literals": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.27.1", + "@babel/plugin-transform-regexp-modifiers": "^7.27.1", + "@babel/plugin-transform-reserved-words": "^7.27.1", + "@babel/plugin-transform-shorthand-properties": "^7.27.1", + "@babel/plugin-transform-spread": "^7.27.1", + "@babel/plugin-transform-sticky-regex": "^7.27.1", + "@babel/plugin-transform-template-literals": "^7.27.1", + "@babel/plugin-transform-typeof-symbol": "^7.27.1", + "@babel/plugin-transform-unicode-escapes": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.27.1", + "@babel/plugin-transform-unicode-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.11.0", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.40.0", + "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", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "dev": true, + "license": "MIT", + "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.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-transform-react-display-name": "^7.27.1", + "@babel/plugin-transform-react-jsx": "^7.27.1", + "@babel/plugin-transform-react-jsx-development": "^7.27.1", + "@babel/plugin-transform-react-pure-annotations": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-typescript": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.27.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.27.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.3", + "@babel/parser": "^7.27.4", + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.3", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.27.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@biomejs/biome": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.1.4.tgz", + "integrity": "sha512-QWlrqyxsU0FCebuMnkvBIkxvPqH89afiJzjMl+z67ybutse590jgeaFdDurE9XYtzpjRGTI1tlUZPGWmbKsElA==", + "dev": true, + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "2.1.4", + "@biomejs/cli-darwin-x64": "2.1.4", + "@biomejs/cli-linux-arm64": "2.1.4", + "@biomejs/cli-linux-arm64-musl": "2.1.4", + "@biomejs/cli-linux-x64": "2.1.4", + "@biomejs/cli-linux-x64-musl": "2.1.4", + "@biomejs/cli-win32-arm64": "2.1.4", + "@biomejs/cli-win32-x64": "2.1.4" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.1.4.tgz", + "integrity": "sha512-sCrNENE74I9MV090Wq/9Dg7EhPudx3+5OiSoQOkIe3DLPzFARuL1dOwCWhKCpA3I5RHmbrsbNSRfZwCabwd8Qg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.1.4.tgz", + "integrity": "sha512-gOEICJbTCy6iruBywBDcG4X5rHMbqCPs3clh3UQ+hRKlgvJTk4NHWQAyHOXvaLe+AxD1/TNX1jbZeffBJzcrOw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.1.4.tgz", + "integrity": "sha512-juhEkdkKR4nbUi5k/KRp1ocGPNWLgFRD4NrHZSveYrD6i98pyvuzmS9yFYgOZa5JhaVqo0HPnci0+YuzSwT2fw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.1.4.tgz", + "integrity": "sha512-nYr7H0CyAJPaLupFE2cH16KZmRC5Z9PEftiA2vWxk+CsFkPZQ6dBRdcC6RuS+zJlPc/JOd8xw3uCCt9Pv41WvQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.1.4.tgz", + "integrity": "sha512-Eoy9ycbhpJVYuR+LskV9s3uyaIkp89+qqgqhGQsWnp/I02Uqg2fXFblHJOpGZR8AxdB9ADy87oFVxn9MpFKUrw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.1.4.tgz", + "integrity": "sha512-lvwvb2SQQHctHUKvBKptR6PLFCM7JfRjpCCrDaTmvB7EeZ5/dQJPhTYBf36BE/B4CRWR2ZiBLRYhK7hhXBCZAg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.1.4.tgz", + "integrity": "sha512-3WRYte7orvyi6TRfIZkDN9Jzoogbv+gSvR+b9VOXUg1We1XrjBg6WljADeVEaKTvOcpVdH0a90TwyOQ6ue4fGw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.1.4.tgz", + "integrity": "sha512-tBc+W7anBPSFXGAoQW+f/+svkpt8/uXfRwDzN1DvnatkRMt16KIYpEi/iw8u9GahJlFv98kgHcIrSsZHZTR0sw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.7.1", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.1", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.1", + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.3", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.9", + "license": "MIT" + }, + "node_modules/@hookform/resolvers": { + "version": "3.10.0", + "license": "MIT", + "peerDependencies": { + "react-hook-form": "^7.0.0" + } + }, + "node_modules/@img/colour": { + "version": "1.0.0", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.4", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.3" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.3", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "dev": true, + "license": "MIT", + "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/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsdoc/salty": { + "version": "0.2.9", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=v12.0.0" + } + }, + "node_modules/@minko-fe/lodash-pro": { + "version": "0.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/lodash-es": "^4.17.9", + "deepmerge": "^4.3.1", + "defu": "^6.1.4", + "destr": "^2.0.3", + "lodash-es": "^4.17.21", + "p-is-promise": "^4.0.0" + } + }, + "node_modules/@minko-fe/postcss-pxtoviewport": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@minko-fe/lodash-pro": "^0.3.0", + "decode-uri-component": "^0.4.1", + "split-on-first": "^3.0.0" + }, + "peerDependencies": { + "postcss": ">=8.0.0" + } + }, + "node_modules/@next/env": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.0.1.tgz", + "integrity": "sha512-LFvlK0TG2L3fEOX77OC35KowL8D7DlFF45C0OvKMC4hy8c/md1RC4UMNDlUGJqfCoCS2VWrZ4dSE6OjaX5+8mw==", + "license": "MIT" + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.0.1.tgz", + "integrity": "sha512-R0YxRp6/4W7yG1nKbfu41bp3d96a0EalonQXiMe+1H9GTHfKxGNCGFNWUho18avRBPsO8T3RmdWuzmfurlQPbg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.0.1.tgz", + "integrity": "sha512-kETZBocRux3xITiZtOtVoVvXyQLB7VBxN7L6EPqgI5paZiUlnsgYv4q8diTNYeHmF9EiehydOBo20lTttCbHAg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.0.1.tgz", + "integrity": "sha512-hWg3BtsxQuSKhfe0LunJoqxjO4NEpBmKkE+P2Sroos7yB//OOX3jD5ISP2wv8QdUwtRehMdwYz6VB50mY6hqAg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.0.1.tgz", + "integrity": "sha512-UPnOvYg+fjAhP3b1iQStcYPWeBFRLrugEyK/lDKGk7kLNua8t5/DvDbAEFotfV1YfcOY6bru76qN9qnjLoyHCQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.0.1.tgz", + "integrity": "sha512-Et81SdWkcRqAJziIgFtsFyJizHoWne4fzJkvjd6V4wEkWTB4MX6J0uByUb0peiJQ4WeAt6GGmMszE5KrXK6WKg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.0.1.tgz", + "integrity": "sha512-qBbgYEBRrC1egcG03FZaVfVxrJm8wBl7vr8UFKplnxNRprctdP26xEv9nJ07Ggq4y1adwa0nz2mz83CELY7N6Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.0.1.tgz", + "integrity": "sha512-cPuBjYP6I699/RdbHJonb3BiRNEDm5CKEBuJ6SD8k3oLam2fDRMKAvmrli4QMDgT2ixyRJ0+DTkiODbIQhRkeQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.0.1.tgz", + "integrity": "sha512-XeEUJsE4JYtfrXe/LaJn3z1pD19fK0Q6Er8Qoufi+HqvdO4LEPyCxLUt4rxA+4RfYo6S9gMlmzCMU2F+AatFqQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "peer": true, + "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.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/detect-libc": { + "version": "1.0.3", + "license": "Apache-2.0", + "optional": true, + "peer": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "license": "BSD-3-Clause" + }, + "node_modules/@radix-ui/number": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.3", + "license": "MIT" + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.7", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-avatar": { + "version": "1.1.10", + "license": "MIT", + "dependencies": { + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-is-hydrated": "0.1.0", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox": { + "version": "1.3.3", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.7", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.2", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.2", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.15", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.1", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.11", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.1.16", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-menu": "2.1.16", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.3", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.7", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-label": { + "version": "2.1.7", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu": { + "version": "2.1.16", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover": { + "version": "1.1.15", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.2.8", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-rect": "1.1.1", + "@radix-ui/react-use-size": "1.1.1", + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.9", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.5", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-progress": { + "version": "1.1.7", + "license": "MIT", + "dependencies": { + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.11", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-select": { + "version": "2.2.6", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.3", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch": { + "version": "1.2.6", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs": { + "version": "1.1.13", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.2.8", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-visually-hidden": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.1", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.2", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.2", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-is-hydrated": { + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.5.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.1", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.1", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.2.3", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/@reduxjs/toolkit": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.9.2.tgz", + "integrity": "sha512-ZAYu/NXkl/OhqTz7rfPaAhY0+e8Fr15jqNxte/2exKUxvHyQ/hcqmdekiN1f+Lcw3pE+34FCgX+26zcUE3duCg==", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", + "immer": "^10.0.3", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "license": "MIT" + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "8.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "8.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "8.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "8.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "8.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "8.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "8.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", + "@svgr/babel-plugin-transform-svg-component": "8.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^8.1.3", + "snake-case": "^3.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "8.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.21.3", + "entities": "^4.4.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "@svgr/hast-util-to-babel-ast": "8.0.0", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cosmiconfig": "^8.1.3", + "deepmerge": "^4.3.1", + "svgo": "^3.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/webpack": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@babel/plugin-transform-react-constant-elements": "^7.21.3", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.21.0", + "@svgr/core": "8.1.0", + "@svgr/plugin-jsx": "8.1.0", + "@svgr/plugin-svgo": "8.1.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tailwindcss/node": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.16.tgz", + "integrity": "sha512-BX5iaSsloNuvKNHRN3k2RcCuTEgASTo77mofW0vmeHkfrDWaoFAFvNHpEgtu0eqyypcyiBkDWzSMxJhp3AUVcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "enhanced-resolve": "^5.18.3", + "jiti": "^2.6.1", + "lightningcss": "1.30.2", + "magic-string": "^0.30.19", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.16" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.16.tgz", + "integrity": "sha512-2OSv52FRuhdlgyOQqgtQHuCgXnS8nFSYRp2tJ+4WZXKgTxqPy7SMSls8c3mPT5pkZ17SBToGM5LHEJBO7miEdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.16", + "@tailwindcss/oxide-darwin-arm64": "4.1.16", + "@tailwindcss/oxide-darwin-x64": "4.1.16", + "@tailwindcss/oxide-freebsd-x64": "4.1.16", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.16", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.16", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.16", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.16", + "@tailwindcss/oxide-linux-x64-musl": "4.1.16", + "@tailwindcss/oxide-wasm32-wasi": "4.1.16", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.16", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.16" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.16.tgz", + "integrity": "sha512-8+ctzkjHgwDJ5caq9IqRSgsP70xhdhJvm+oueS/yhD5ixLhqTw9fSL1OurzMUhBwE5zK26FXLCz2f/RtkISqHA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.16.tgz", + "integrity": "sha512-C3oZy5042v2FOALBZtY0JTDnGNdS6w7DxL/odvSny17ORUnaRKhyTse8xYi3yKGyfnTUOdavRCdmc8QqJYwFKA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.16.tgz", + "integrity": "sha512-vjrl/1Ub9+JwU6BP0emgipGjowzYZMjbWCDqwA2Z4vCa+HBSpP4v6U2ddejcHsolsYxwL5r4bPNoamlV0xDdLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.16.tgz", + "integrity": "sha512-TSMpPYpQLm+aR1wW5rKuUuEruc/oOX3C7H0BTnPDn7W/eMw8W+MRMpiypKMkXZfwH8wqPIRKppuZoedTtNj2tg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.16.tgz", + "integrity": "sha512-p0GGfRg/w0sdsFKBjMYvvKIiKy/LNWLWgV/plR4lUgrsxFAoQBFrXkZ4C0w8IOXfslB9vHK/JGASWD2IefIpvw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.16.tgz", + "integrity": "sha512-DoixyMmTNO19rwRPdqviTrG1rYzpxgyYJl8RgQvdAQUzxC1ToLRqtNJpU/ATURSKgIg6uerPw2feW0aS8SNr/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.16.tgz", + "integrity": "sha512-H81UXMa9hJhWhaAUca6bU2wm5RRFpuHImrwXBUvPbYb+3jo32I9VIwpOX6hms0fPmA6f2pGVlybO6qU8pF4fzQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.16.tgz", + "integrity": "sha512-ZGHQxDtFC2/ruo7t99Qo2TTIvOERULPl5l0K1g0oK6b5PGqjYMga+FcY1wIUnrUxY56h28FxybtDEla+ICOyew==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.16.tgz", + "integrity": "sha512-Oi1tAaa0rcKf1Og9MzKeINZzMLPbhxvm7rno5/zuP1WYmpiG0bEHq4AcRUiG2165/WUzvxkW4XDYCscZWbTLZw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.16.tgz", + "integrity": "sha512-B01u/b8LteGRwucIBmCQ07FVXLzImWESAIMcUU6nvFt/tYsQ6IHz8DmZ5KtvmwxD+iTYBtM1xwoGXswnlu9v0Q==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.5.0", + "@emnapi/runtime": "^1.5.0", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.0.7", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.16.tgz", + "integrity": "sha512-zX+Q8sSkGj6HKRTMJXuPvOcP8XfYON24zJBRPlszcH1Np7xuHXhWn8qfFjIujVzvH3BHU+16jBXwgpl20i+v9A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.16.tgz", + "integrity": "sha512-m5dDFJUEejbFqP+UXVstd4W/wnxA4F61q8SoL+mqTypId2T2ZpuxosNSgowiCnLp2+Z+rivdU0AqpfgiD7yCBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/postcss": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.16.tgz", + "integrity": "sha512-Qn3SFGPXYQMKR/UtqS+dqvPrzEeBZHrFA92maT4zijCVggdsXnDBMsPFJo1eArX3J+O+Gi+8pV4PkqjLCNBk3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "4.1.16", + "@tailwindcss/oxide": "4.1.16", + "postcss": "^8.4.41", + "tailwindcss": "4.1.16" + } + }, + "node_modules/@trulience/react-sdk": { + "version": "1.0.98", + "resolved": "https://registry.npmjs.org/@trulience/react-sdk/-/react-sdk-1.0.98.tgz", + "integrity": "sha512-8ZNdYyATwXl5idwzyfpF7CWWPY1AmhweZzDy1XDdLsHKjyFmStZpDBhYyTvr/h/rDHahT+rBCkYJhgt42MkT+w==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.11.0", + "react-dom": ">=16.11.0" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/lodash": { + "version": "4.17.18", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/markdown-it": { + "version": "14.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/linkify-it": "^5", + "@types/mdurl": "^2" + } + }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.24.tgz", + "integrity": "sha512-FE5u0ezmi6y9OZEzlJfg37mqqf6ZDSF2V/NLjUyGrR9uTZ7Sb9F7bLNZ03S4XVUNRWGA7Ck4c1kK+YnuWjl+DA==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/react": { + "version": "19.2.2", + "devOptional": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.2", + "devOptional": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@types/react-redux": { + "version": "7.1.34", + "dev": true, + "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/react-redux/node_modules/redux": { + "version": "4.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.15.0", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agora-rtc-sdk-ng": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/agora-rtc-sdk-ng/-/agora-rtc-sdk-ng-4.23.0.tgz", + "integrity": "sha512-/DVTowwsU0PpwTT/xXOa9UAB3qlVpLty2Cxsn+B0mEKHbXTd4P4cgeLaSCbxQFqDhYQAqpwyClxC5ABYBal5yA==", + "dependencies": { + "@agora-js/media": "4.23.0", + "@agora-js/report": "4.23.0", + "@agora-js/shared": "4.23.0", + "agora-rte-extension": "^1.2.4", + "axios": "^1.7.7", + "formdata-polyfill": "^4.0.7", + "pako": "^2.1.0", + "ua-parser-js": "^0.7.34", + "webrtc-adapter": "8.2.0" + } + }, + "node_modules/agora-rte-extension": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/agora-rte-extension/-/agora-rte-extension-1.2.4.tgz", + "integrity": "sha512-0ovZz1lbe30QraG1cU+ji7EnQ8aUu+Hf3F+a8xPml3wPOyUQEK6CTdxV9kMecr9t+fIDrGeW7wgJTsM1DQE7Nw==" + }, + "node_modules/agora-rtm": { + "version": "2.2.3", + "license": "Apache", + "peerDependencies": { + "agora-rtc-sdk-ng": "4.23.0" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-hidden": { + "version": "1.2.6", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.1.tgz", + "integrity": "sha512-hU4EGxxt+j7TQijx1oYdAjw4xuIp1wRQSsbMFwSthCWeBQur1eF+qJ5iQ5sN3Tw8YRzQNKb8jszgBdMDVqwJcw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.13", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.4", + "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", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.11.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.3", + "core-js-compat": "^3.40.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.4" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/bluebird": { + "version": "3.7.2", + "dev": true, + "license": "MIT" + }, + "node_modules/boolbase": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.25.0", + "dev": true, + "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" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001718", + "electron-to-chromium": "^1.5.160", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001724", + "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" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/catharsis": { + "version": "0.9.0", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.15" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "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/chokidar": { + "version": "4.0.3", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/class-variance-authority": { + "version": "0.7.1", + "license": "Apache-2.0", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "license": "MIT" + }, + "node_modules/clsx": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "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==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/core-js-compat": { + "version": "3.43.0", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.25.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree/node_modules/mdn-data": { + "version": "2.0.28", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/csstype": { + "version": "3.1.3", + "devOptional": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-uri-component": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defu": { + "version": "6.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/destr": { + "version": "2.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "devOptional": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.172", + "dev": true, + "license": "ISC" + }, + "node_modules/enhanced-resolve": { + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/escodegen": { + "version": "1.14.3", + "dev": true, + "license": "BSD-2-Clause", + "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/escodegen/node_modules/estraverse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "dev": true, + "license": "BSD-2-Clause", + "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", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/framer-motion": { + "version": "12.23.26", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.26.tgz", + "integrity": "sha512-cPcIhgR42xBn1Uj+PzOyheMtZ73H927+uWPDVhUMqxy8UHt6Okavb6xIz9J/phFUHUj0OncR6UvMfJTXoc/LKA==", + "dependencies": { + "motion-dom": "^12.23.23", + "motion-utils": "^12.23.6", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.2", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "8.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "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==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/immer": { + "version": "10.1.1", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/immutable": { + "version": "5.1.3", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/js2xmlparser": { + "version": "4.0.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "xmlcreate": "^2.0.4" + } + }, + "node_modules/jsdoc": { + "version": "4.0.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@babel/parser": "^7.20.15", + "@jsdoc/salty": "^0.2.1", + "@types/markdown-it": "^14.1.1", + "bluebird": "^3.7.2", + "catharsis": "^0.9.0", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.2", + "klaw": "^3.0.0", + "markdown-it": "^14.1.0", + "markdown-it-anchor": "^8.6.7", + "marked": "^4.0.10", + "mkdirp": "^1.0.4", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.1.0", + "underscore": "~1.13.2" + }, + "bin": { + "jsdoc": "jsdoc.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/klaw": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightningcss": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", + "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.30.2", + "lightningcss-darwin-arm64": "1.30.2", + "lightningcss-darwin-x64": "1.30.2", + "lightningcss-freebsd-x64": "1.30.2", + "lightningcss-linux-arm-gnueabihf": "1.30.2", + "lightningcss-linux-arm64-gnu": "1.30.2", + "lightningcss-linux-arm64-musl": "1.30.2", + "lightningcss-linux-x64-gnu": "1.30.2", + "lightningcss-linux-x64-musl": "1.30.2", + "lightningcss-win32-arm64-msvc": "1.30.2", + "lightningcss-win32-x64-msvc": "1.30.2" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", + "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", + "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", + "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", + "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", + "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", + "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", + "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", + "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", + "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", + "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", + "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/linkify-it": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "dev": true, + "license": "MIT" + }, + "node_modules/long": { + "version": "5.3.2", + "license": "Apache-2.0" + }, + "node_modules/lower-case": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lru-cache/node_modules/yallist": { + "version": "3.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/lucide-react": { + "version": "0.546.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.546.0.tgz", + "integrity": "sha512-Z94u6fKT43lKeYHiVyvyR8fT7pwCzDu7RyMPpTvh054+xahSgj4HFQ+NmflvzdXsoAjYGdCguGaFKYuvq0ThCQ==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/markdown-it": { + "version": "14.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-it-anchor": { + "version": "8.6.7", + "dev": true, + "license": "Unlicense", + "peerDependencies": { + "@types/markdown-it": "*", + "markdown-it": "*" + } + }, + "node_modules/marked": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/mdurl": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "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==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "5.1.6", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/motion-dom": { + "version": "12.23.23", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.23.23.tgz", + "integrity": "sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA==", + "dependencies": { + "motion-utils": "^12.23.6" + } + }, + "node_modules/motion-utils": { + "version": "12.23.6", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.23.6.tgz", + "integrity": "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==" + }, + "node_modules/ms": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/next": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/next/-/next-16.0.1.tgz", + "integrity": "sha512-e9RLSssZwd35p7/vOa+hoDFggUZIUbZhIUSLZuETCwrCVvxOs87NamoUzT+vbcNAL8Ld9GobBnWOA6SbV/arOw==", + "license": "MIT", + "dependencies": { + "@next/env": "16.0.1", + "@swc/helpers": "0.5.15", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.4.31", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=20.9.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "16.0.1", + "@next/swc-darwin-x64": "16.0.1", + "@next/swc-linux-arm64-gnu": "16.0.1", + "@next/swc-linux-arm64-musl": "16.0.1", + "@next/swc-linux-x64-gnu": "16.0.1", + "@next/swc-linux-x64-musl": "16.0.1", + "@next/swc-win32-arm64-msvc": "16.0.1", + "@next/swc-win32-x64-msvc": "16.0.1", + "sharp": "^0.34.4" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.51.1", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next-themes": { + "version": "0.4.6", + "license": "MIT", + "peerDependencies": { + "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "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" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/no-case": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "dev": true, + "license": "MIT" + }, + "node_modules/nth-check": { + "version": "2.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.8.3", + "dev": true, + "license": "MIT", + "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/p-is-promise": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pako": { + "version": "2.1.0", + "license": "(MIT AND Zlib)" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "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/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/protobufjs": { + "version": "7.5.4", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/protobufjs-cli": { + "version": "1.1.3", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "chalk": "^4.0.0", + "escodegen": "^1.13.0", + "espree": "^9.0.0", + "estraverse": "^5.1.0", + "glob": "^8.0.0", + "jsdoc": "^4.0.0", + "minimist": "^1.2.0", + "semver": "^7.1.2", + "tmp": "^0.2.1", + "uglify-js": "^3.7.7" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "protobufjs": "^7.0.0" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/react": { + "version": "19.2.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-colorful": { + "version": "5.6.1", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.0", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.0" + } + }, + "node_modules/react-hook-form": { + "version": "7.65.0", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18 || ^19" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "dev": true, + "license": "MIT" + }, + "node_modules/react-redux": { + "version": "9.2.0", + "license": "MIT", + "dependencies": { + "@types/use-sync-external-store": "^0.0.6", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25 || ^19", + "react": "^18.0 || ^19", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll": { + "version": "2.7.1", + "license": "MIT", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "license": "MIT", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "license": "MIT", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/redux": { + "version": "5.0.1", + "license": "MIT" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "license": "MIT", + "peerDependencies": { + "redux": "^5.0.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regexpu-core": { + "version": "6.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.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", + "dev": true, + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.12.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.0.2" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/requizzle": { + "version": "0.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21" + } + }, + "node_modules/reselect": { + "version": "5.1.1", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.10", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/sass": { + "version": "1.93.2", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "license": "MIT" + }, + "node_modules/sdp": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/sdp/-/sdp-3.2.1.tgz", + "integrity": "sha512-lwsAIzOPlH8/7IIjjz3K0zYBk7aBVVcvjMwt3M4fLxpjMYyy7i3I97SLHebgn4YBjirkzfp3RvRDWSKsh/+WFw==" + }, + "node_modules/semver": { + "version": "7.7.2", + "devOptional": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.34.4", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.0", + "semver": "^7.7.2" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.4", + "@img/sharp-darwin-x64": "0.34.4", + "@img/sharp-libvips-darwin-arm64": "1.2.3", + "@img/sharp-libvips-darwin-x64": "1.2.3", + "@img/sharp-libvips-linux-arm": "1.2.3", + "@img/sharp-libvips-linux-arm64": "1.2.3", + "@img/sharp-libvips-linux-ppc64": "1.2.3", + "@img/sharp-libvips-linux-s390x": "1.2.3", + "@img/sharp-libvips-linux-x64": "1.2.3", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.3", + "@img/sharp-libvips-linuxmusl-x64": "1.2.3", + "@img/sharp-linux-arm": "0.34.4", + "@img/sharp-linux-arm64": "0.34.4", + "@img/sharp-linux-ppc64": "0.34.4", + "@img/sharp-linux-s390x": "0.34.4", + "@img/sharp-linux-x64": "0.34.4", + "@img/sharp-linuxmusl-arm64": "0.34.4", + "@img/sharp-linuxmusl-x64": "0.34.4", + "@img/sharp-wasm32": "0.34.4", + "@img/sharp-win32-arm64": "0.34.4", + "@img/sharp-win32-ia32": "0.34.4", + "@img/sharp-win32-x64": "0.34.4" + } + }, + "node_modules/snake-case": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/sonner": { + "version": "1.7.4", + "license": "MIT", + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-on-first": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/svgo": { + "version": "3.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/tailwind-merge": { + "version": "2.6.0", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.16.tgz", + "integrity": "sha512-pONL5awpaQX4LN5eiv7moSiSPd/DLDzKVRJz8Q9PgzmAdd1R4307GQS2ZpfiN7ZmekdQrfhZZiSE5jkLR4WNaA==", + "license": "MIT" + }, + "node_modules/tailwindcss-animate": { + "version": "1.0.7", + "license": "MIT", + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders" + } + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tmp": { + "version": "0.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ua-parser-js": { + "version": "0.7.41", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.41.tgz", + "integrity": "sha512-O3oYyCMPYgNNHuO7Jjk3uacJWZF8loBgwrfd/5LE/HyZ3lUIOdniQ7DNXJcIgZbwioZxk0fLfI4EVnetdiX5jg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/uc.micro": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/underscore": { + "version": "1.13.7", + "dev": true, + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "6.21.0", + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "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", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "dev": true, + "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" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "license": "MIT", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sync-external-store": { + "version": "1.5.0", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webrtc-adapter": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-8.2.0.tgz", + "integrity": "sha512-umxCMgedPAVq4Pe/jl3xmelLXLn4XZWFEMR5Iipb5wJ+k1xMX0yC4ZY9CueZUU1MjapFxai1tFGE7R/kotH6Ww==", + "dependencies": { + "sdp": "^3.0.2" + }, + "engines": { + "node": ">=6.0.0", + "npm": ">=3.10.0" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/xmlcreate": { + "version": "2.0.4", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/zod": { + "version": "3.25.76", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/ai_agents/agents/examples/doodler/frontend/package.json b/ai_agents/agents/examples/doodler/frontend/package.json new file mode 100644 index 0000000000..e46256ea9d --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/package.json @@ -0,0 +1,70 @@ +{ + "name": "ten_agent_playground", + "version": "0.6.0", + "private": true, + "engines": { + "node": ">=20" + }, + "scripts": { + "dev": "next dev --turbopack", + "build": "next build", + "start": "next start", + "lint": "biome check --write", + "proto": "pbjs -t json-module -w commonjs -o src/protobuf/SttMessage.js src/protobuf/SttMessage.proto" + }, + "dependencies": { + "@hookform/resolvers": "^3.10.0", + "@radix-ui/react-avatar": "^1.1.10", + "@radix-ui/react-checkbox": "^1.3.3", + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-dropdown-menu": "^2.1.16", + "@radix-ui/react-label": "^2.1.7", + "@radix-ui/react-popover": "^1.1.15", + "@radix-ui/react-progress": "^1.1.7", + "@radix-ui/react-select": "^2.2.6", + "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-switch": "^1.2.6", + "@radix-ui/react-tabs": "^1.1.13", + "@radix-ui/react-tooltip": "^1.2.8", + "@reduxjs/toolkit": "^2.9.2", + "@trulience/react-sdk": "^1.0.98", + "agora-rtc-sdk-ng": "^4.23.0", + "agora-rtm": "^2.2.3", + "axios": "^1.13.1", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "framer-motion": "^12.23.26", + "lucide-react": "^0.546.0", + "next": "16.0.1", + "next-themes": "^0.4.6", + "protobufjs": "^7.5.4", + "react": "19.2.0", + "react-colorful": "^5.6.1", + "react-dom": "19.2.0", + "react-hook-form": "^7.65.0", + "react-redux": "^9.2.0", + "redux": "^5.0.1", + "sonner": "^1.7.4", + "tailwind-merge": "^2.6.0", + "tailwindcss-animate": "^1.0.7", + "zod": "^3.25.76" + }, + "devDependencies": { + "@biomejs/biome": "2.1.4", + "@minko-fe/postcss-pxtoviewport": "^1.5.0", + "@svgr/webpack": "^8.1.0", + "@tailwindcss/postcss": "^4.1.16", + "@types/node": "^20.19.24", + "@types/react": "19.2.2", + "@types/react-dom": "19.2.2", + "@types/react-redux": "^7.1.34", + "postcss": "^8.5.6", + "protobufjs-cli": "^1.1.3", + "tailwindcss": "^4.1.16", + "typescript": "^5.9.3" + }, + "overrides": { + "@types/react": "19.2.2", + "@types/react-dom": "19.2.2" + } +} diff --git a/ai_agents/agents/examples/doodler/frontend/postcss.config.js b/ai_agents/agents/examples/doodler/frontend/postcss.config.js new file mode 100644 index 0000000000..b41430fb65 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/postcss.config.js @@ -0,0 +1,11 @@ +/** @type {import('postcss-load-config').Config} */ +module.exports = { + plugins: { + "@tailwindcss/postcss": {}, + "@minko-fe/postcss-pxtoviewport": { + viewportWidth: 375, + exclude: /node_modules/, + include: /\/src\/platform\/mobile\//, + }, + }, +}; diff --git a/ai_agents/agents/examples/doodler/frontend/src/app/api/agents/start/route.tsx b/ai_agents/agents/examples/doodler/frontend/src/app/api/agents/start/route.tsx new file mode 100644 index 0000000000..e67e2ceaf6 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/app/api/agents/start/route.tsx @@ -0,0 +1,54 @@ +import axios from "axios"; +import { type NextRequest, NextResponse } from "next/server"; + +/** + * Handles the POST request to start an agent. + * + * @param request - The NextRequest object representing the incoming request. + * @returns A NextResponse object representing the response to be sent back to the client. + */ +export async function POST(request: NextRequest) { + try { + const { AGENT_SERVER_URL } = process.env; + + // Check if environment variables are available + if (!AGENT_SERVER_URL) { + throw "Environment variables are not available"; + } + + const body = await request.json(); + const { + request_id, + channel_name, + user_uid, + graph_name, + language, + voice_type, + properties, + } = body; + + // Send a POST request to start the agent + const response = await axios.post(`${AGENT_SERVER_URL}/start`, { + request_id, + channel_name, + user_uid, + graph_name, + // Get the graph properties based on the graph name, language, and voice type + properties: properties, + }); + + const responseData = response.data; + + return NextResponse.json(responseData, { status: response.status }); + } catch (error) { + if (error instanceof Response) { + const errorData = await error.json(); + return NextResponse.json(errorData, { status: error.status }); + } else { + return NextResponse.json( + { code: "1", data: null, msg: "Internal Server Error" }, + { status: 500 } + ); + } + } +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/app/favicon.ico b/ai_agents/agents/examples/doodler/frontend/src/app/favicon.ico new file mode 100644 index 0000000000..92b8b6ba0c Binary files /dev/null and b/ai_agents/agents/examples/doodler/frontend/src/app/favicon.ico differ diff --git a/ai_agents/agents/examples/doodler/frontend/src/app/global.css b/ai_agents/agents/examples/doodler/frontend/src/app/global.css new file mode 100644 index 0000000000..dc3883acf7 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/app/global.css @@ -0,0 +1,556 @@ +@import "tailwindcss"; + +@plugin 'tailwindcss-animate'; + +@custom-variant dark (&:is(.dark *)); + +@theme { + --radius-lg: var(--radius); + --radius-md: calc(var(--radius) - 2px); + --radius-sm: calc(var(--radius) - 4px); + + --color-background: hsl(var(--background)); + --color-foreground: hsl(var(--foreground)); + + --color-card: hsl(var(--card)); + --color-card-foreground: hsl(var(--card-foreground)); + + --color-popover: hsl(var(--popover)); + --color-popover-foreground: hsl(var(--popover-foreground)); + + --color-primary: hsl(var(--primary)); + --color-primary-foreground: hsl(var(--primary-foreground)); + + --color-secondary: hsl(var(--secondary)); + --color-secondary-foreground: hsl(var(--secondary-foreground)); + + --color-muted: hsl(var(--muted)); + --color-muted-foreground: hsl(var(--muted-foreground)); + + --color-accent: hsl(var(--accent)); + --color-accent-foreground: hsl(var(--accent-foreground)); + + --color-destructive: hsl(var(--destructive)); + --color-destructive-foreground: hsl(var(--destructive-foreground)); + + --color-border: hsl(var(--border)); + --color-input: hsl(var(--input)); + --color-ring: hsl(var(--ring)); + + --color-chart-1: hsl(var(--chart-1)); + --color-chart-2: hsl(var(--chart-2)); + --color-chart-3: hsl(var(--chart-3)); + --color-chart-4: hsl(var(--chart-4)); + --color-chart-5: hsl(var(--chart-5)); +} + +/* + The default border color has changed to `currentcolor` in Tailwind CSS v4, + so we've added these compatibility styles to make sure everything still + looks the same as it did with Tailwind CSS v3. + + If we ever want to remove these styles, we need to add an explicit border + color utility to any element that depends on these defaults. +*/ +@layer base { + *, + ::after, + ::before, + ::backdrop, + ::file-selector-button { + border-color: var(--color-gray-200, currentcolor); + } +} + +@layer utilities { + * { + box-sizing: border-box; + padding: 0; + margin: 0; + } + + html, + body { + color-scheme: light; + font-family: ui-rounded, "PingFang SC", system-ui, -apple-system, + BlinkMacSystemFont, "Segoe UI", sans-serif; + height: 100%; + } + + a { + color: inherit; + text-decoration: none; + } + + html { + background-color: hsl(var(--background)); + } +} + +@layer base { + :root { + --background: 43 100% 97%; + --foreground: 24 22% 12%; + --card: 0 0% 100%; + --card-foreground: 24 22% 12%; + --popover: 0 0% 100%; + --popover-foreground: 24 22% 12%; + --primary: 20 92% 55%; + --primary-foreground: 0 0% 100%; + --secondary: 40 52% 92%; + --secondary-foreground: 24 22% 12%; + --muted: 40 35% 90%; + --muted-foreground: 24 10% 38%; + --accent: 190 70% 92%; + --accent-foreground: 24 22% 12%; + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 0 0% 98%; + --border: 24 18% 82%; + --input: 24 18% 82%; + --ring: 20 92% 55%; + --chart-1: 12 76% 61%; + --chart-2: 173 58% 39%; + --chart-3: 197 37% 24%; + --chart-4: 43 74% 66%; + --chart-5: 27 87% 67%; + --radius: 0.75rem; + } + .dark { + --background: 0 0% 3.9%; + --foreground: 0 0% 98%; + --card: 0 0% 3.9%; + --card-foreground: 0 0% 98%; + --popover: 0 0% 3.9%; + --popover-foreground: 0 0% 98%; + --primary: 0 0% 98%; + --primary-foreground: 0 0% 9%; + --secondary: 0 0% 14.9%; + --secondary-foreground: 0 0% 98%; + --muted: 0 0% 14.9%; + --muted-foreground: 0 0% 63.9%; + --accent: 0 0% 14.9%; + --accent-foreground: 0 0% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 0% 98%; + --border: 0 0% 14.9%; + --input: 0 0% 14.9%; + --ring: 0 0% 83.1%; + --chart-1: 220 70% 50%; + --chart-2: 160 60% 45%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-5: 340 75% 55%; + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} + +@layer utilities { + .doodle-paper { + background-color: hsl(var(--background)); + background-image: + radial-gradient( + 1200px 820px at 10% 10%, + rgba(255, 214, 165, 0.55), + transparent 65% + ), + radial-gradient( + 1000px 700px at 86% 18%, + rgba(168, 231, 255, 0.4), + transparent 62% + ), + radial-gradient( + 980px 740px at 28% 92%, + rgba(255, 168, 214, 0.26), + transparent 62% + ), + radial-gradient( + 820px 580px at 72% 72%, + rgba(255, 235, 140, 0.24), + transparent 60% + ), + linear-gradient(180deg, rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.55)); + } + + .doodle-wash { + background-image: + radial-gradient(circle at 12% 22%, rgba(255, 110, 180, 0.16), transparent 52%), + radial-gradient(circle at 88% 18%, rgba(96, 211, 255, 0.18), transparent 48%), + radial-gradient(circle at 30% 82%, rgba(121, 235, 178, 0.16), transparent 52%), + radial-gradient(circle at 72% 82%, rgba(255, 210, 120, 0.14), transparent 50%); + mix-blend-mode: multiply; + filter: blur(18px); + opacity: 0.55; + } + + .doodle-tile { + background-image: + url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20width%3D%27320%27%20height%3D%27320%27%20viewBox%3D%270%200%20320%20320%27%20fill%3D%27none%27%20stroke%3D%27%23111%27%20stroke-width%3D%273%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Ccircle%20cx%3D%2732%27%20cy%3D%2732%27%20r%3D%2710%27/%3E%3Cpath%20d%3D%27M32%206v8M32%2050v8M6%2032h8M50%2032h8M14%2014l6%206M44%2044l6%206M50%2014l-6%206M14%2050l6-6%27/%3E%3Cpath%20d%3D%27M96%2020l6%2014%2014%206-14%206-6%2014-6-14-14-6%2014-6%206-14z%27/%3E%3Cpath%20d%3D%27M144%2044l4%2010%2010%204-10%204-4%2010-4-10-10-4%2010-4%204-10z%27/%3E%3Cpath%20d%3D%27M232%2022c-8-10-24-6-24%206%200%2014%2024%2026%2024%2026s24-12%2024-26c0-12-16-16-24-6z%27/%3E%3Cpath%20d%3D%27M68%20104c0-8%208-14%2016-10%206-10%2024-6%2022%208%2010%202%2012%2016%200%2018-8%202-28%202-38-2-8-4-6-14%200-14z%27/%3E%3Cpath%20d%3D%27M200%2088l30-8%2020%2018-8%2024-26%204-18-18%202-20z%27/%3E%3Cpath%20d%3D%27M34%20170c24-18%2044-12%2062-2%27/%3E%3Cpath%20d%3D%27M90%20158l12%204-8%2010%27/%3E%3Cpath%20d%3D%27M140%20150c8-10%2024-14%2036-4-8%2012-20%2018-36%2012%200-4%202-6%204-8%27/%3E%3Cpath%20d%3D%27M220%20164l10%2018%2020%204-16%2010-4%2020-10-16-20-4%2016-10%204-20z%27/%3E%3Cpath%20d%3D%27M80%20228c-10-6-22-4-28%206%2010%208%2022%2010%2030%206%27/%3E%3Cpath%20d%3D%27M160%20230c-6-16%204-34%2022-38-16%2010-18%2032-4%2044-12%204-22%200-18-6z%27/%3E%3Cpath%20d%3D%27M230%20236l0%2030%27/%3E%3Cpath%20d%3D%27M218%20252l24%200%27/%3E%3Cpath%20d%3D%27M252%20244l12%208-12%208%27/%3E%3C/svg%3E"); + background-repeat: repeat; + background-size: 240px 240px; + background-position: 0 0; + mix-blend-mode: multiply; + opacity: 0.24; + } + + .crayon-border { + position: relative; + border-radius: 22px; + border: 2px solid rgba(18, 18, 18, 0.55); + background-color: rgba(255, 255, 255, 0.85); + } + + .crayon-border::after { + content: ""; + position: absolute; + inset: -4px; + border-radius: inherit; + border: 2px dashed rgba(18, 18, 18, 0.2); + opacity: 0.6; + transform: rotate(-0.4deg); + pointer-events: none; + } + + .crayon-control { + position: relative; + border: 2px solid rgba(18, 18, 18, 0.55); + border-radius: 999px; + box-shadow: 0 3px 0 rgba(18, 18, 18, 0.08); + } + + .crayon-control::after { + content: ""; + position: absolute; + inset: -3px; + border-radius: inherit; + border: 2px dashed rgba(18, 18, 18, 0.2); + opacity: 0.55; + transform: rotate(-0.25deg); + pointer-events: none; + } + + .crayon-bubble { + position: relative; + border-radius: 18px; + border-width: 2px; + border-style: solid; + box-shadow: 0 3px 0 rgba(18, 18, 18, 0.08); + } + + .crayon-bubble::after { + content: ""; + position: absolute; + inset: -3px; + border-radius: inherit; + border: 2px dashed rgba(18, 18, 18, 0.18); + opacity: 0.55; + transform: rotate(0.3deg); + pointer-events: none; + } + + .doodle-dream { + background-image: + radial-gradient(circle at 20% 20%, rgba(124, 255, 250, 0.38), transparent 55%), + radial-gradient(circle at 80% 25%, rgba(255, 122, 216, 0.3), transparent 55%), + radial-gradient(circle at 45% 75%, rgba(255, 204, 102, 0.26), transparent 60%), + radial-gradient(circle at 70% 80%, rgba(116, 198, 255, 0.26), transparent 65%); + filter: blur(22px) saturate(1.15); + transform: scale(1.08); + } + + .doodle-dream--classic { + filter: blur(24px) saturate(1.05); + } + + .doodle-dream--neon { + filter: blur(18px) saturate(1.45) contrast(1.06); + } + + .doodle-vignette { + background: radial-gradient( + closest-side at 50% 44%, + transparent 68%, + rgba(32, 16, 8, 0.14) + ); + mix-blend-mode: multiply; + opacity: 0.55; + } + + .doodle-board { + background-image: + linear-gradient(180deg, rgba(255, 255, 255, 0.74), rgba(255, 255, 255, 0.52)), + radial-gradient( + 900px 600px at 20% 0%, + rgba(255, 237, 213, 0.6), + transparent 62% + ), + radial-gradient( + 900px 600px at 80% 100%, + rgba(230, 245, 255, 0.58), + transparent 62% + ); + border: 1px solid rgba(0, 0, 0, 0.09); + box-shadow: 0 28px 70px rgba(34, 18, 10, 0.18); + backdrop-filter: blur(10px); + } + + .doodle-board-grid { + background-image: + repeating-linear-gradient( + 0deg, + rgba(0, 0, 0, 0.04) 0, + rgba(0, 0, 0, 0.04) 1px, + transparent 1px, + transparent 32px + ), + repeating-linear-gradient( + 90deg, + rgba(0, 0, 0, 0.04) 0, + rgba(0, 0, 0, 0.04) 1px, + transparent 1px, + transparent 32px + ); + opacity: 0.45; + } + + .doodle-palette { + border: 1px solid rgba(0, 0, 0, 0.11); + border-radius: 24px; + background: rgba(255, 255, 255, 0.72); + box-shadow: 0 18px 50px rgba(34, 18, 10, 0.18); + padding: 14px; + backdrop-filter: blur(12px); + } + + .doodle-logo { + display: inline-flex; + align-items: center; + gap: 10px; + border: 1px solid rgba(0, 0, 0, 0.1); + background: rgba(255, 255, 255, 0.72); + padding: 10px 14px; + border-radius: 9999px; + box-shadow: 0 8px 24px rgba(34, 18, 10, 0.12); + backdrop-filter: blur(12px); + } + + .doodle-logo__mark { + width: 12px; + height: 12px; + border-radius: 4px; + background: linear-gradient(135deg, #f97316, #ff7ad8); + box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.06); + } + + .doodle-logo__text { + font-weight: 800; + letter-spacing: 0.02em; + } + + .toy-board-frame { + border-radius: 56px; + padding: 18px 18px 14px; + background: linear-gradient(180deg, #4b86ff 0%, #2e59d9 60%, #254ab8 100%); + border: 1px solid rgba(255, 255, 255, 0.18); + box-shadow: + 0 26px 70px rgba(24, 25, 58, 0.25), + inset 0 10px 22px rgba(255, 255, 255, 0.18), + inset 0 -14px 30px rgba(0, 0, 0, 0.18); + position: relative; + z-index: 0; + } + + .toy-board-frame::before { + content: ""; + position: absolute; + inset: 12px 12px auto 12px; + height: 84px; + border-radius: 48px; + background: radial-gradient( + 700px 120px at 50% 0%, + rgba(255, 255, 255, 0.22), + transparent 70% + ); + pointer-events: none; + } + + .toy-board-frame::after { + content: ""; + position: absolute; + inset: 18px 22px 10px 22px; + border-radius: 54px; + background: rgba(16, 22, 56, 0.28); + transform: translateY(22px); + filter: blur(22px); + opacity: 0.65; + z-index: -1; + pointer-events: none; + } + + .toy-board-sticker { + height: 44px; + width: 44px; + border-radius: 9999px; + border: 1px solid rgba(0, 0, 0, 0.12); + box-shadow: + 0 10px 22px rgba(0, 0, 0, 0.18), + inset 0 10px 18px rgba(255, 255, 255, 0.28); + position: relative; + transition: transform 120ms ease, box-shadow 120ms ease; + } + + .toy-board-sticker:hover { + transform: translateY(-1px); + box-shadow: + 0 14px 26px rgba(0, 0, 0, 0.2), + inset 0 10px 18px rgba(255, 255, 255, 0.28); + } + + .toy-board-sticker__shine { + position: absolute; + inset: 9px 10px auto 10px; + height: 14px; + border-radius: 9999px; + background: rgba(255, 255, 255, 0.38); + transform: rotate(-14deg); + pointer-events: none; + } + + .toy-board-bezel { + border-radius: 48px; + padding: 12px; + background: linear-gradient(180deg, rgba(255, 255, 255, 0.88), rgba(233, 238, 248, 0.9)); + border: 1px solid rgba(0, 0, 0, 0.08); + box-shadow: + inset 0 16px 28px rgba(255, 255, 255, 0.5), + inset 0 -18px 26px rgba(0, 0, 0, 0.12); + } + + .toy-board-screen { + border-radius: 38px; + background: linear-gradient(180deg, rgba(248, 248, 248, 0.95), rgba(236, 236, 236, 0.95)); + border: 1px solid rgba(0, 0, 0, 0.1); + box-shadow: + inset 0 2px 0 rgba(255, 255, 255, 0.7), + inset 0 -18px 40px rgba(0, 0, 0, 0.18); + position: relative; + } + + .toy-board-screen::after { + content: ""; + position: absolute; + inset: 10px; + border-radius: 30px; + border: 2px dashed rgba(17, 17, 17, 0.2); + box-shadow: 0 3px 0 rgba(18, 18, 18, 0.08); + pointer-events: none; + } + + .toy-board-pen-slot { + display: flex; + align-items: center; + justify-content: center; + } + + .toy-board-pen-slot__well { + width: 100%; + height: 100%; + border-radius: 44px; + background: linear-gradient(180deg, #2b56d3, #2244b6 75%, #1a3795); + border: 1px solid rgba(0, 0, 0, 0.14); + box-shadow: + inset 0 16px 24px rgba(255, 255, 255, 0.16), + inset 0 -18px 30px rgba(0, 0, 0, 0.22); + position: relative; + overflow: hidden; + } + + .toy-board-pen-slot__cord { + position: absolute; + left: 8px; + top: 34px; + width: 28px; + height: 10px; + border-radius: 9999px; + background: rgba(255, 255, 255, 0.22); + box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18); + transform: rotate(6deg); + } + + .toy-board-pen-slot__stylus { + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + padding-top: 10px; + } + + .toy-board-bottom { + position: relative; + margin-top: 14px; + height: 44px; + border-radius: 9999px; + background: linear-gradient(180deg, rgba(28, 54, 148, 0.55), rgba(12, 22, 70, 0.28)); + box-shadow: + inset 0 10px 18px rgba(255, 255, 255, 0.12), + inset 0 -14px 22px rgba(0, 0, 0, 0.25); + } + + .toy-board-bottom__rail { + position: absolute; + left: 16px; + right: 66px; + top: 16px; + height: 12px; + border-radius: 9999px; + background: rgba(11, 18, 32, 0.22); + box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.25); + } + + .toy-board-bottom__knob { + position: absolute; + right: 14px; + top: 8px; + height: 28px; + width: 44px; + border-radius: 9999px; + background: linear-gradient(180deg, #ffe16f, #ffb000); + border: 1px solid rgba(0, 0, 0, 0.18); + box-shadow: + 0 10px 18px rgba(0, 0, 0, 0.22), + inset 0 10px 14px rgba(255, 255, 255, 0.26); + } +} + +/* Custom Scrollbar Styles */ +::-webkit-scrollbar { + width: 10px; +} + +::-webkit-scrollbar-track { + background: transparent; + border-radius: 5px; +} + +::-webkit-scrollbar-thumb { + background: hsl(var(--muted)); + border-radius: 5px; +} + +::-webkit-scrollbar-thumb:hover { + background: hsl(var(--muted-foreground)); +} + +/* For Firefox */ +* { + scrollbar-width: thin; + scrollbar-color: hsl(var(--muted)) transparent; +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/app/layout.tsx b/ai_agents/agents/examples/doodler/frontend/src/app/layout.tsx new file mode 100644 index 0000000000..43d75fef25 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/app/layout.tsx @@ -0,0 +1,60 @@ +// import { ConfigProvider } from "antd"; + +import type { Metadata, Viewport } from "next"; +import { ThemeProvider } from "@/components/theme-provider"; +import { Toaster } from "@/components/ui/sonner"; +import { StoreProvider } from "@/store"; + +import "./global.css"; + +export const metadata: Metadata = { + title: "TEN Agent | Real-Time Multimodal AI Agent", + description: + "TEN Agent is an open-source multimodal AI agent that can speak, see, and access a knowledge base(RAG).", + appleWebApp: { + capable: true, + statusBarStyle: "black", + }, +}; + +export const viewport: Viewport = { + width: "device-width", + initialScale: 1, + minimumScale: 1, + maximumScale: 1, + userScalable: false, + viewportFit: "cover", +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + {/* */} + + {children} + {/* */} + + + + + ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/app/page.tsx b/ai_agents/agents/examples/doodler/frontend/src/app/page.tsx new file mode 100644 index 0000000000..6d24891c36 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/app/page.tsx @@ -0,0 +1,13 @@ +"use client"; + +import React from "react"; +import AuthInitializer from "@/components/authInitializer"; +import ImmersiveShell from "@/components/Doodler/ImmersiveShell"; + +export default function Home() { + return ( + + + + ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/assets/background.jpg b/ai_agents/agents/examples/doodler/frontend/src/assets/background.jpg new file mode 100644 index 0000000000..0276234386 Binary files /dev/null and b/ai_agents/agents/examples/doodler/frontend/src/assets/background.jpg differ diff --git a/ai_agents/agents/examples/doodler/frontend/src/assets/cam_mute.svg b/ai_agents/agents/examples/doodler/frontend/src/assets/cam_mute.svg new file mode 100644 index 0000000000..a4640ae4db --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/assets/cam_mute.svg @@ -0,0 +1,3 @@ + + + diff --git a/ai_agents/agents/examples/doodler/frontend/src/assets/cam_unmute.svg b/ai_agents/agents/examples/doodler/frontend/src/assets/cam_unmute.svg new file mode 100644 index 0000000000..1eebfaa63f --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/assets/cam_unmute.svg @@ -0,0 +1,3 @@ + + + diff --git a/ai_agents/agents/examples/doodler/frontend/src/assets/color_picker.svg b/ai_agents/agents/examples/doodler/frontend/src/assets/color_picker.svg new file mode 100644 index 0000000000..fb9bb33e2a --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/assets/color_picker.svg @@ -0,0 +1,17 @@ + + + + + + + + + + diff --git a/ai_agents/agents/examples/doodler/frontend/src/assets/github.svg b/ai_agents/agents/examples/doodler/frontend/src/assets/github.svg new file mode 100644 index 0000000000..e6566c4143 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/assets/github.svg @@ -0,0 +1,3 @@ + + + diff --git a/ai_agents/agents/examples/doodler/frontend/src/assets/info.svg b/ai_agents/agents/examples/doodler/frontend/src/assets/info.svg new file mode 100644 index 0000000000..8ca9951146 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/assets/info.svg @@ -0,0 +1,3 @@ + + + diff --git a/ai_agents/agents/examples/doodler/frontend/src/assets/logo.svg b/ai_agents/agents/examples/doodler/frontend/src/assets/logo.svg new file mode 100644 index 0000000000..af99893ae2 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/assets/logo.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ai_agents/agents/examples/doodler/frontend/src/assets/logo_small.svg b/ai_agents/agents/examples/doodler/frontend/src/assets/logo_small.svg new file mode 100644 index 0000000000..34e755bdc4 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/assets/logo_small.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ai_agents/agents/examples/doodler/frontend/src/assets/mic_mute.svg b/ai_agents/agents/examples/doodler/frontend/src/assets/mic_mute.svg new file mode 100644 index 0000000000..dd4a17ddf2 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/assets/mic_mute.svg @@ -0,0 +1,3 @@ + + + diff --git a/ai_agents/agents/examples/doodler/frontend/src/assets/mic_unmute.svg b/ai_agents/agents/examples/doodler/frontend/src/assets/mic_unmute.svg new file mode 100644 index 0000000000..18e78236f6 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/assets/mic_unmute.svg @@ -0,0 +1,3 @@ + + + diff --git a/ai_agents/agents/examples/doodler/frontend/src/assets/network/average.svg b/ai_agents/agents/examples/doodler/frontend/src/assets/network/average.svg new file mode 100644 index 0000000000..9a27072f82 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/assets/network/average.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/ai_agents/agents/examples/doodler/frontend/src/assets/network/disconnected.svg b/ai_agents/agents/examples/doodler/frontend/src/assets/network/disconnected.svg new file mode 100644 index 0000000000..b7db1d719b --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/assets/network/disconnected.svg @@ -0,0 +1,9 @@ + + + + + diff --git a/ai_agents/agents/examples/doodler/frontend/src/assets/network/excellent.svg b/ai_agents/agents/examples/doodler/frontend/src/assets/network/excellent.svg new file mode 100644 index 0000000000..55b9fc9e6f --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/assets/network/excellent.svg @@ -0,0 +1,6 @@ + + + + diff --git a/ai_agents/agents/examples/doodler/frontend/src/assets/network/good.svg b/ai_agents/agents/examples/doodler/frontend/src/assets/network/good.svg new file mode 100644 index 0000000000..8c36a7e792 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/assets/network/good.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/ai_agents/agents/examples/doodler/frontend/src/assets/network/poor.svg b/ai_agents/agents/examples/doodler/frontend/src/assets/network/poor.svg new file mode 100644 index 0000000000..d9df02385e --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/assets/network/poor.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/ai_agents/agents/examples/doodler/frontend/src/assets/pdf.svg b/ai_agents/agents/examples/doodler/frontend/src/assets/pdf.svg new file mode 100644 index 0000000000..dc67f4d571 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/assets/pdf.svg @@ -0,0 +1,3 @@ + + + diff --git a/ai_agents/agents/examples/doodler/frontend/src/assets/transcription.svg b/ai_agents/agents/examples/doodler/frontend/src/assets/transcription.svg new file mode 100644 index 0000000000..8b887a6ff0 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/assets/transcription.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/ai_agents/agents/examples/doodler/frontend/src/assets/voice.svg b/ai_agents/agents/examples/doodler/frontend/src/assets/voice.svg new file mode 100644 index 0000000000..86a880b053 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/assets/voice.svg @@ -0,0 +1,3 @@ + + + diff --git a/ai_agents/agents/examples/doodler/frontend/src/common/constant.ts b/ai_agents/agents/examples/doodler/frontend/src/common/constant.ts new file mode 100644 index 0000000000..a66ec605a6 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/common/constant.ts @@ -0,0 +1,147 @@ +import type { + ColorItem, + GraphOptionItem, + IOptions, + ITrulienceSettings, + LanguageOptionItem, + VoiceOptionItem, +} from "@/types"; +export const GITHUB_URL = "https://github.com/TEN-framework/TEN-Agent"; +export const OPTIONS_KEY = "__options__"; +export const DEFAULT_OPTIONS: IOptions = { + channel: "", + userName: "", + userId: 0, + appId: "", + token: "", +}; +export const DESCRIPTION = + "TEN Agent is an open-source multimodal AI agent that can speak, see, and access a knowledge base(RAG)."; +export const LANGUAGE_OPTIONS: LanguageOptionItem[] = [ + { + label: "English", + value: "en-US", + }, + { + label: "Chinese", + value: "zh-CN", + }, + { + label: "Korean", + value: "ko-KR", + }, + { + label: "Japanese", + value: "ja-JP", + }, +]; +export const GRAPH_OPTIONS: GraphOptionItem[] = [ + { + label: "Voice Agent - OpenAI LLM + Azure TTS", + value: "va_openai_azure", + }, + { + label: "Voice Agent with Vision - OpenAI LLM + Azure TTS", + value: "camera_va_openai_azure", + }, + //{ + // label: "Voice Agent with Knowledge - RAG + Qwen LLM + Cosy TTS", + // value: "va_qwen_rag" + // }, +]; + +export const isRagGraph = (graphName: string) => { + return graphName === "va_qwen_rag"; +}; + +export const VOICE_OPTIONS: VoiceOptionItem[] = [ + { + label: "Male", + value: "male", + }, + { + label: "Female", + value: "female", + }, +]; + +export enum VideoSourceType { + CAMERA = "camera", + SCREEN = "screen", +} + +export const VIDEO_SOURCE_OPTIONS = [ + { + label: "Camera", + value: VideoSourceType.CAMERA, + }, + { + label: "Screen Share", + value: VideoSourceType.SCREEN, + }, +]; + +export const COLOR_LIST: ColorItem[] = [ + { + active: "#0888FF", + default: "#143354", + }, + { + active: "#563FD8", + default: "#2C2553", + }, + { + active: "#18A957", + default: "#173526", + }, + { + active: "#FFAB08", + default: "#423115", + }, + { + active: "#FD5C63", + default: "#462629", + }, + { + active: "#E225B2", + default: "#481C3F", + }, +]; + +export type VoiceTypeMap = { + [voiceType: string]: string; +}; + +export type VendorNameMap = { + [vendorName: string]: VoiceTypeMap; +}; + +export type LanguageMap = { + [language: string]: VendorNameMap; +}; + +export enum EMobileActiveTab { + AGENT = "agent", + CHAT = "chat", +} + +export const MOBILE_ACTIVE_TAB_MAP = { + [EMobileActiveTab.AGENT]: "Agent", + [EMobileActiveTab.CHAT]: "Chat", +}; + +export const isLLM = (extensionName: string) => { + return extensionName === "llm" || extensionName === "v2v"; +}; + +export const isEditModeOn = process.env.NEXT_PUBLIC_EDIT_GRAPH_MODE === "true"; + +export const TRULIENCE_SETTINGS_KEY = "__trulience__"; +export const DEFAULT_TRULIENCE_OPTIONS: ITrulienceSettings = { + enabled: false, + avatarId: "", + avatarToken: "", + avatarDesktopLargeWindow: false, + animationURL: "https://trulience.com", + trulienceSDK: "https://trulience.com/sdk/trulience.sdk.js", +}; diff --git a/ai_agents/agents/examples/doodler/frontend/src/common/graph.ts b/ai_agents/agents/examples/doodler/frontend/src/common/graph.ts new file mode 100644 index 0000000000..fc96081db1 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/common/graph.ts @@ -0,0 +1,578 @@ +import type { ModuleRegistry } from "./moduleConfig"; + +export namespace AddonDef { + export type AttributeType = + | "string" + | "bool" + | "int32" + | "int64" + | "Uint32" + | "Uint64" + | "float64" + | "array" + | "buf"; + + export type Attribute = { + type: AttributeType; + }; + + export type PropertyDefinition = { + name: string; + attributes: Attribute; + }; + + export type Command = { + name: string; + property?: PropertyDefinition[]; + required?: string[]; + result?: { + property: PropertyDefinition[]; + required?: string[]; + }; + }; + + export type ApiEndpoint = { + name: string; + property?: PropertyDefinition[]; + }; + + export type Api = { + property?: { properties: Record }; + cmd_in?: Command[]; + cmd_out?: Command[]; + data_in?: ApiEndpoint[]; + data_out?: ApiEndpoint[]; + audio_frame_in?: ApiEndpoint[]; + audio_frame_out?: ApiEndpoint[]; + video_frame_in?: ApiEndpoint[]; + video_frame_out?: ApiEndpoint[]; + }; + + export type Module = { + name: string; + defaultProperty: Property; + api: Api; + }; +} + +type Property = { + [key: string]: any; +}; + +type Node = { + name: string; + addon: string; + extensionGroup: string; + app: string; + property?: Property; +}; +type Command = { + name: string; // Command name + dest: Array; // Destination connections +}; + +type Data = { + name: string; // Data type name + dest: Array; // Destination connections +}; + +type AudioFrame = { + name: string; // Audio frame type name + dest: Array; // Destination connections +}; + +type VideoFrame = { + name: string; // Video frame type name + dest: Array; // Destination connections +}; + +type MsgConversion = { + type: string; // Type of message conversion + rules: Array<{ + path: string; // Path in the data structure + conversionMode: string; // Mode of conversion (e.g., "replace", "append") + value?: string; // Optional value for the conversion + originalPath?: string; // Optional original path for mapping + }>; + keepOriginal?: boolean; // Whether to keep the original data +}; + +type Destination = { + app: string; // Application identifier + extension: string; // Extension name + msgConversion?: MsgConversion; // Optional message conversion rules +}; + +type Connection = { + app: string; // Application identifier + extension: string; // Extension name + cmd?: Array; // Optional command connections + data?: Array; // Optional data connections + audio_frame?: Array; // Optional audio frame connections + video_frame?: Array; // Optional video frame connections +}; + +type Graph = { + graph_id: string; + name: string; + autoStart: boolean; + nodes: Node[]; + connections: Connection[]; +}; + +enum GraphConnProtocol { + CMD = "cmd", + DATA = "data", + AUDIO_FRAME = "audio_frame", + VIDEO_FRAME = "video_frame", +} + +class GraphEditor { + private static sharedApp: string = "localhost"; + + /** + * Set a shared app value. + */ + static setApp(app: string): void { + GraphEditor.sharedApp = app; + } + + /** + * Add a node to the graph + */ + static addNode( + graph: Graph, + addon: string, + name: string, + group: string = "default", + properties: Record = {} + ): Node { + if (graph.nodes.some((node) => node.name === name)) { + throw new Error( + `Node with name "${name}" already exists in graph "${graph.name}".` + ); + } + + const node: Node = { + name, + addon, + extensionGroup: group, + app: GraphEditor.sharedApp, + property: properties, + }; + + graph.nodes.push(node); + return node; + } + + /** + * Remove a node from the graph + */ + static removeNode(graph: Graph, nodeName: string): Node { + const nodeIndex = graph.nodes.findIndex((node) => node.name === nodeName); + if (nodeIndex === -1) { + throw new Error(`Node "${nodeName}" not found in graph "${graph.name}".`); + } + const node = graph.nodes.splice(nodeIndex, 1)[0]; + return node; + } + + /** + * Update node properties + */ + static updateNode( + graph: Graph, + nodeName: string, + properties: Record + ): void { + const node = graph.nodes.find((node) => node.name === nodeName); + if (!node) { + throw new Error(`Node "${nodeName}" not found in graph "${graph.name}".`); + } + + // Update properties (remove property if value is empty) + node.property = { + ...node.property, + ...Object.fromEntries( + Object.entries(properties).filter(([_, value]) => value !== "") + ), + }; + } + + static updateNodeProperty( + graph: Graph, + nodeName: string, + properties: Record + ): boolean { + const node = GraphEditor.findNode(graph, nodeName); + if (!node) return false; + + node.property = { + ...node.property, + ...Object.fromEntries( + Object.entries(properties).filter(([_, value]) => value !== "") + ), + }; + + return true; + } + + static removeNodeProperties( + graph: Graph, + nodeName: string, + properties: string[] + ): boolean { + const node = GraphEditor.findNode(graph, nodeName); + if (!node) return false; + + properties.forEach((prop) => { + if (node.property) delete node.property[prop]; + }); + + return true; + } + + /** + * Add a connection to the graph across all protocols (cmd, data, audio_frame, video_frame) + */ + static addConnection( + graph: Graph, + source: string, + destination: string, + protocolLabel: GraphConnProtocol, + protocolName: string // Name for the protocol object + ): void { + // Find the source connection in the graph + let connection = graph.connections.find( + (conn) => conn.extension === source + ); + + if (!connection) { + // If no connection exists, create a new one + connection = { + app: GraphEditor.sharedApp, + extension: source, + }; + graph.connections.push(connection); + } + + // Handle protocol-specific addition + const protocolField = protocolLabel.toLowerCase() as keyof Connection; + if (!connection[protocolField]) { + connection[protocolField] = [] as any; + } + + const protocolArray = connection[protocolField] as Array< + Command | Data | AudioFrame | VideoFrame + >; + + // Check if the protocol object exists + let protocolObject = protocolArray.find( + (item) => item.name === protocolName + ); + if (!protocolObject) { + protocolObject = { + name: protocolName, + dest: [], + }; + protocolArray.push(protocolObject); + } + + // Check if the destination already exists + if (protocolObject.dest.some((dest) => dest.extension === destination)) { + throw new Error( + `Destination "${destination}" already exists in protocol "${protocolLabel}" with name "${protocolName}".` + ); + } + + // Add the destination + protocolObject.dest.push({ + app: GraphEditor.sharedApp, + extension: destination, + }); + } + static addOrUpdateConnection( + graph: Graph, + source: string, + destination: string, + protocolLabel: GraphConnProtocol, + protocolName: string // Explicit name of the protocol object + ): void { + const connection = GraphEditor.findConnection(graph, source); + + if (connection) { + // Add or update destination in the existing connection + const protocolField = protocolLabel.toLowerCase() as keyof Connection; + if (!connection[protocolField]) { + connection[protocolField] = [] as any; + } + + const protocolArray = connection[protocolField] as Array< + Command | Data | AudioFrame | VideoFrame + >; + + // Find the protocol object by name + let protocolObject = protocolArray.find( + (item) => item.name === protocolName + ); + if (!protocolObject) { + // Create a new protocol object if it doesn't exist + protocolObject = { + name: protocolName, + dest: [], + }; + protocolArray.push(protocolObject); + } + + // Check if the destination already exists + if (!protocolObject.dest.some((dest) => dest.extension === destination)) { + // Add the new destination + protocolObject.dest.push({ + app: GraphEditor.sharedApp, + extension: destination, + }); + } + } else { + // Add a new connection if none exists + GraphEditor.addConnection( + graph, + source, + destination, + protocolLabel, + protocolName + ); + } + } + /** + * Remove a connection from the graph across all protocols (cmd, data, audio_frame, video_frame) + */ + static removeConnection( + graph: Graph, + source: string, + destination?: string, + protocolLabel?: GraphConnProtocol, + protocolName?: string // Optional name of the protocol object + ): void { + // Find the source connection in the graph + const connectionIndex = graph.connections.findIndex( + (conn) => conn.extension === source + ); + + if (connectionIndex === -1) { + console.warn( + `Source "${source}" not found in the graph. Operation ignored.` + ); + return; // Exit the function if the connection does not exist + } + + const connection = graph.connections[connectionIndex]; + + // If protocolLabel is provided, handle protocol-specific removal + if (protocolLabel) { + const protocolField = protocolLabel.toLowerCase() as keyof Connection; + const protocolArray = connection[protocolField] as Array< + Command | Data | AudioFrame | VideoFrame + >; + + if (!protocolArray) { + console.warn( + `Protocol "${protocolLabel}" does not exist for source "${source}". Operation ignored.` + ); + return; // Exit the function if the protocol does not exist + } + + const protocolObjectIndex = protocolArray.findIndex( + (item) => item.name === protocolName + ); + + if (protocolObjectIndex === -1) { + console.warn( + `Protocol object with name "${protocolName}" not found in protocol "${protocolLabel}". Operation ignored.` + ); + return; // Exit the function if the protocol object does not exist + } + + if (destination) { + // Remove a specific destination + protocolArray[protocolObjectIndex].dest = protocolArray[ + protocolObjectIndex + ].dest.filter((dest) => dest.extension !== destination); + + // Remove the protocol object if it has no destinations + if (protocolArray[protocolObjectIndex].dest.length === 0) { + protocolArray.splice(protocolObjectIndex, 1); + } + } else { + // Remove the entire protocol object + protocolArray.splice(protocolObjectIndex, 1); + } + } else { + // If no protocolLabel is provided, remove the entire connection + graph.connections.splice(connectionIndex, 1); + } + + // Clean up empty connections + GraphEditor.removeEmptyConnections(graph); + } + + static findNode(graph: Graph, nodeName: string): Node | null { + return graph.nodes.find((node) => node.name === nodeName) || null; + } + + static findNodeByPredicate( + graph: Graph, + predicate: (node: Node) => boolean + ): Node | null { + return graph.nodes.find(predicate) || null; + } + + static findConnection(graph: Graph, extension: string): Connection | null { + return ( + graph.connections.find((conn) => conn.extension === extension) || null + ); + } + + static removeEmptyConnections(graph: Graph): void { + graph.connections = graph.connections.filter((connection) => { + // Filter each protocol to remove empty destination objects + connection.cmd = Array.isArray(connection.cmd) + ? connection.cmd.filter((cmd) => cmd.dest?.length > 0) + : undefined; + if (!connection.cmd?.length) delete connection.cmd; + + connection.data = Array.isArray(connection.data) + ? connection.data.filter((data) => data.dest?.length > 0) + : undefined; + if (!connection.data?.length) delete connection.data; + + connection.audio_frame = Array.isArray(connection.audio_frame) + ? connection.audio_frame.filter((audio) => audio.dest?.length > 0) + : undefined; + if (!connection.audio_frame?.length) delete connection.audio_frame; + + connection.video_frame = Array.isArray(connection.video_frame) + ? connection.video_frame.filter((video) => video.dest?.length > 0) + : undefined; + if (!connection.video_frame?.length) delete connection.video_frame; + + // Check if at least one protocol remains + return ( + connection.cmd?.length || + connection.data?.length || + connection.audio_frame?.length || + connection.video_frame?.length + ); + }); + } + + static removeNodeAndConnections(graph: Graph, addon: string): void { + // Remove the node + const node = GraphEditor.removeNode(graph, addon); + + // Remove all connections involving this node + graph.connections = graph.connections.filter((connection) => { + const isSource = connection.extension === `${node.name}`; + const protocols = ["cmd", "data", "audio_frame", "video_frame"] as const; + + protocols.forEach((protocol) => { + if (connection[protocol]) { + connection[protocol].forEach( + (item) => + (item.dest = item.dest.filter((d) => d.extension !== node.name)) + ); + } + }); + + // Return true if connection still has content, false to remove it + return ( + !isSource && + (connection.cmd?.length || + connection.data?.length || + connection.audio_frame?.length || + connection.video_frame?.length) + ); + }); + // Clean up empty connections + GraphEditor.removeEmptyConnections(graph); + } + + /** + * Link a tool to an LLM node by creating the appropriate connections. + */ + static linkTool( + graph: Graph, + llmNode: Node, + toolNode: Node, + tool: ModuleRegistry.ToolModule + ): void { + // Create the connection from the LLM node to the tool node + GraphEditor.addOrUpdateConnection( + graph, + `${llmNode.name}`, + `${toolNode.name}`, + GraphConnProtocol.CMD, + "tool_call" + ); + + // Create the connection from the tool node back to the LLM node + GraphEditor.addOrUpdateConnection( + graph, + `${toolNode.name}`, + `${llmNode.name}`, + GraphConnProtocol.CMD, + "tool_register" + ); + + const rtcModule = GraphEditor.findNodeByPredicate(graph, (node) => + node.addon.includes("rtc") + ); + if (toolNode.addon.includes("vision") && rtcModule) { + // Create the connection from the RTC node to the tool node to deliver video frame + GraphEditor.addOrUpdateConnection( + graph, + `${rtcModule.name}`, + `${toolNode.name}`, + GraphConnProtocol.VIDEO_FRAME, + "video_frame" + ); + } + + const messageCollector = GraphEditor.findNodeByPredicate(graph, (node) => + node.addon.includes("message_collector") + ); + if (tool.options.outputContentText && messageCollector) { + GraphEditor.addOrUpdateConnection( + graph, + `${toolNode.name}`, + `${messageCollector.name}`, + GraphConnProtocol.DATA, + "content_data" + ); + } + } + + static enableRTCVideoSubscribe(graph: Graph, enabled: boolean): void { + const rtcNode = GraphEditor.findNodeByPredicate(graph, (node) => + node.addon.includes("rtc") + ); + if (!rtcNode) { + throw new Error("RTC node not found in the graph."); + } + + if (enabled) { + GraphEditor.updateNodeProperty(graph, rtcNode.name, { + subscribe_video_pix_fmt: 4, + subscribe_video: true, + }); + } else { + GraphEditor.removeNodeProperties(graph, rtcNode.name, [ + "subscribe_video_pix_fmt", + "subscribe_video", + ]); + } + } +} + +export type { Graph, Node, Connection, Command, Destination }; + +export { GraphEditor, GraphConnProtocol as ProtocolLabel }; diff --git a/ai_agents/agents/examples/doodler/frontend/src/common/hooks.ts b/ai_agents/agents/examples/doodler/frontend/src/common/hooks.ts new file mode 100644 index 0000000000..19f62d946c --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/common/hooks.ts @@ -0,0 +1,227 @@ +"use client"; + +import type { IMicrophoneAudioTrack, IRemoteAudioTrack } from "agora-rtc-sdk-ng"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { useDispatch, useSelector, useStore } from "react-redux"; +import type { AddonDef, Graph, Node } from "@/common/graph"; +import { + type ModuleRegistry, + moduleRegistry, + toolModuleRegistry, +} from "@/common/moduleConfig"; +import { initializeGraphData, updateGraph } from "@/store/reducers/global"; +import type { AppDispatch, AppStore, RootState } from "../store"; +import { deepMerge, normalizeFrequencies } from "./utils"; +// import { Grid } from "antd" + +// const { useBreakpoint } = Grid; + +export const useAppDispatch = useDispatch.withTypes(); +export const useAppSelector = useSelector.withTypes(); +export const useAppStore = useStore.withTypes(); + +export const useMultibandTrackVolume = ( + track?: IMicrophoneAudioTrack | IRemoteAudioTrack | MediaStreamTrack, + bands: number = 5, + loPass: number = 100, + hiPass: number = 600 +) => { + const [frequencyBands, setFrequencyBands] = useState([]); + + useEffect(() => { + if (!track) { + return setFrequencyBands(new Array(bands).fill(new Float32Array(0))); + } + + const ctx = new AudioContext(); + const finTrack = + track instanceof MediaStreamTrack ? track : track.getMediaStreamTrack(); + const mediaStream = new MediaStream([finTrack]); + const source = ctx.createMediaStreamSource(mediaStream); + const analyser = ctx.createAnalyser(); + analyser.fftSize = 2048; + + source.connect(analyser); + + const bufferLength = analyser.frequencyBinCount; + const dataArray = new Float32Array(bufferLength); + + const updateVolume = () => { + analyser.getFloatFrequencyData(dataArray); + let frequencies: Float32Array = new Float32Array(dataArray.length); + for (let i = 0; i < dataArray.length; i++) { + frequencies[i] = dataArray[i]; + } + frequencies = frequencies.slice(loPass, hiPass); + + const normalizedFrequencies = normalizeFrequencies(frequencies); + const chunkSize = Math.ceil(normalizedFrequencies.length / bands); + const chunks: Float32Array[] = []; + for (let i = 0; i < bands; i++) { + chunks.push( + normalizedFrequencies.slice(i * chunkSize, (i + 1) * chunkSize) + ); + } + + setFrequencyBands(chunks); + }; + + const interval = setInterval(updateVolume, 10); + + return () => { + source.disconnect(); + clearInterval(interval); + }; + }, [track, loPass, hiPass, bands]); + + return frequencyBands; +}; + +export const useAutoScroll = (ref: React.RefObject) => { + const callback: MutationCallback = (mutationList, observer) => { + mutationList.forEach((mutation) => { + switch (mutation.type) { + case "childList": + if (!ref.current) { + return; + } + ref.current.scrollTop = ref.current.scrollHeight; + break; + } + }); + }; + + useEffect(() => { + if (!ref.current) { + return; + } + const observer = new MutationObserver(callback); + observer.observe(ref.current, { + childList: true, + subtree: true, + }); + + return () => { + observer.disconnect(); + }; + }, [ref]); +}; + +// export const useSmallScreen = () => { +// const screens = useBreakpoint(); + +// const xs = useMemo(() => { +// return !screens.sm && screens.xs +// }, [screens]) + +// const sm = useMemo(() => { +// return !screens.md && screens.sm +// }, [screens]) + +// return { +// xs, +// sm, +// isSmallScreen: xs || sm +// } +// } + +export const usePrevious = (value: unknown) => { + const ref = useRef(value); + + useEffect(() => { + ref.current = value; + }, [value]); + + return ref.current; +}; + +const useGraphs = () => { + const dispatch = useAppDispatch(); + const selectedGraphId = useAppSelector( + (state) => state.global.selectedGraphId + ); + const graphMap = useAppSelector((state) => state.global.graphMap); + const selectedGraph = graphMap[selectedGraphId]; + const addonModules: AddonDef.Module[] = useAppSelector( + (state) => state.global.addonModules + ); + + const initialize = async () => { + await dispatch(initializeGraphData()); + }; + + const update = async (graph: Graph, updates: Partial) => { + await dispatch(updateGraph({ graph, updates })).unwrap(); + }; + + const getGraphNodeAddonByName = useCallback( + (nodeName: string) => { + if (!selectedGraph) { + return null; + } + const node = selectedGraph.nodes.find( + (node: Node) => node.name === nodeName + ); + if (!node) { + return null; + } + return node; + }, + [selectedGraph] + ); + + const getInstalledAndRegisteredModulesMap = useCallback(() => { + const groupedModules: Record< + ModuleRegistry.NonToolModuleType, + ModuleRegistry.Module[] + > = { + stt: [], + tts: [], + llm: [], + v2v: [], + }; + + addonModules.forEach((addonModule) => { + const registeredModule = moduleRegistry[addonModule.name]; + if (registeredModule && registeredModule.type !== "tool") { + groupedModules[registeredModule.type].push(registeredModule); + } + }); + + return groupedModules; + }, [addonModules]); + + const getInstalledAndRegisteredToolModules = useCallback(() => { + const toolModules: ModuleRegistry.ToolModule[] = []; + + addonModules.forEach((addonModule) => { + const registeredModule = toolModuleRegistry[addonModule.name]; + if (registeredModule && registeredModule.type === "tool") { + toolModules.push(registeredModule); + } + }); + + return toolModules; + }, [addonModules]); + + const installedAndRegisteredModulesMap = useMemo( + () => getInstalledAndRegisteredModulesMap(), + [getInstalledAndRegisteredModulesMap] + ); + + const installedAndRegisteredToolModules = useMemo( + () => getInstalledAndRegisteredToolModules(), + [getInstalledAndRegisteredToolModules] + ); + + return { + initialize, + getGraphNodeAddonByName, + updateGraph: update, + selectedGraph, + installedAndRegisteredModulesMap, + installedAndRegisteredToolModules, + }; +}; + +export { useGraphs }; diff --git a/ai_agents/agents/examples/doodler/frontend/src/common/index.ts b/ai_agents/agents/examples/doodler/frontend/src/common/index.ts new file mode 100644 index 0000000000..98abd60bcf --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/common/index.ts @@ -0,0 +1,6 @@ +export * from "./constant"; +export * from "./hooks"; +export * from "./mock"; +export * from "./request"; +export * from "./storage"; +export * from "./utils"; diff --git a/ai_agents/agents/examples/doodler/frontend/src/common/mock.ts b/ai_agents/agents/examples/doodler/frontend/src/common/mock.ts new file mode 100644 index 0000000000..3bfe6779aa --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/common/mock.ts @@ -0,0 +1,39 @@ +import { EMessageDataType, EMessageType, type IChatItem } from "@/types"; +import { getRandomUserId } from "./utils"; + +const SENTENCES = [ + "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium.", + "Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit.", + "Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit.", + "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", + "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.", + "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", +]; + +export const genRandomParagraph = (num: number = 0): string => { + let paragraph = ""; + for (let i = 0; i < num; i++) { + const randomIndex = Math.floor(Math.random() * SENTENCES.length); + paragraph += SENTENCES[randomIndex] + " "; + } + + return paragraph.trim(); +}; + +export const genRandomChatList = (num: number = 10): IChatItem[] => { + const arr: IChatItem[] = []; + for (let i = 0; i < num; i++) { + const type = Math.random() > 0.5 ? EMessageType.AGENT : EMessageType.USER; + arr.push({ + userId: getRandomUserId(), + userName: type == "agent" ? EMessageType.AGENT : "You", + text: genRandomParagraph(3), + type, + data_type: EMessageDataType.TEXT, + time: Date.now(), + }); + } + + return arr; +}; diff --git a/ai_agents/agents/examples/doodler/frontend/src/common/moduleConfig.ts b/ai_agents/agents/examples/doodler/frontend/src/common/moduleConfig.ts new file mode 100644 index 0000000000..c2863402cf --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/common/moduleConfig.ts @@ -0,0 +1,299 @@ +export namespace ModuleRegistry { + export enum ModuleType { + STT = "stt", + LLM = "llm", + V2V = "v2v", + TTS = "tts", + TOOL = "tool", + } + + export interface Module { + name: string; + type: ModuleType; + label: string; + } + + export type NonToolModuleType = Exclude; + export type NonToolModule = Module & { type: NonToolModuleType }; + export enum Modalities { + Video = "video", + Audio = "audio", + Text = "text", + } + export interface LLMModuleOptions { + inputModalities: Modalities[]; + } + export interface V2VModuleOptions { + inputModalities: Modalities[]; + } + export interface ToolModuleOptions { + outputContentText?: boolean; + } + // Extending Module to define LLMModule with options + export interface LLMModule extends Module { + type: ModuleType.LLM; // Ensuring it's specific to LLM + options: LLMModuleOptions; + } + export interface V2VModule extends Module { + type: ModuleType.V2V; + options: LLMModuleOptions; + } + export interface ToolModule extends Module { + type: ModuleType.TOOL; + options: ToolModuleOptions; + } +} + +// Custom labels for specific keys +export const ModuleTypeLabels: Record< + ModuleRegistry.NonToolModuleType, + string +> = { + [ModuleRegistry.ModuleType.STT]: "STT (Speech to Text)", + [ModuleRegistry.ModuleType.LLM]: "LLM (Large Language Model)", + [ModuleRegistry.ModuleType.TTS]: "TTS (Text to Speech)", + [ModuleRegistry.ModuleType.V2V]: "LLM v2v (V2V Large Language Model)", +}; + +export const sttModuleRegistry: Record = { + deepgram_asr_python: { + name: "deepgram_asr_python", + type: ModuleRegistry.ModuleType.STT, + label: "Deepgram STT", + }, + transcribe_asr_python: { + name: "transcribe_asr_python", + type: ModuleRegistry.ModuleType.STT, + label: "Transcribe STT", + }, + speechmatics_asr_python: { + name: "speechmatics_asr_python", + type: ModuleRegistry.ModuleType.STT, + label: "Speechmatics STT", + }, +}; + +export const llmModuleRegistry: Record = { + openai_chatgpt_python: { + name: "openai_chatgpt_python", + type: ModuleRegistry.ModuleType.LLM, + label: "OpenAI ChatGPT", + options: { inputModalities: [ModuleRegistry.Modalities.Text] }, + }, + dify_python: { + name: "dify_python", + type: ModuleRegistry.ModuleType.LLM, + label: "Dify Chat Bot", + options: { inputModalities: [ModuleRegistry.Modalities.Text] }, + }, + coze_python_async: { + name: "coze_python_async", + type: ModuleRegistry.ModuleType.LLM, + label: "Coze Chat Bot", + options: { inputModalities: [ModuleRegistry.Modalities.Text] }, + }, + gemini_llm_python: { + name: "gemini_llm_python", + type: ModuleRegistry.ModuleType.LLM, + label: "Gemini LLM", + options: { inputModalities: [ModuleRegistry.Modalities.Text] }, + }, + bedrock_llm_python: { + name: "bedrock_llm_python", + type: ModuleRegistry.ModuleType.LLM, + label: "Bedrock LLM", + options: { + inputModalities: [ + ModuleRegistry.Modalities.Text, + ModuleRegistry.Modalities.Video, + ], + }, + }, +}; + +export const ttsModuleRegistry: Record = { + azure_tts: { + name: "azure_tts", + type: ModuleRegistry.ModuleType.TTS, + label: "Azure TTS", + }, + cartesia_tts: { + name: "cartesia_tts", + type: ModuleRegistry.ModuleType.TTS, + label: "Cartesia TTS", + }, + cosy_tts_python: { + name: "cosy_tts_python", + type: ModuleRegistry.ModuleType.TTS, + label: "Cosy TTS", + }, + elevenlabs_tts_python: { + name: "elevenlabs_tts_python", + type: ModuleRegistry.ModuleType.TTS, + label: "Elevenlabs TTS", + }, + fish_audio_tts_python: { + name: "fish_audio_tts_python", + type: ModuleRegistry.ModuleType.TTS, + label: "Fish Audio TTS", + }, + minimax_tts_python: { + name: "minimax_tts_python", + type: ModuleRegistry.ModuleType.TTS, + label: "Minimax TTS", + }, + polly_tts: { + name: "polly_tts", + type: ModuleRegistry.ModuleType.TTS, + label: "Polly TTS", + }, + neuphonic_tts: { + name: "neuphonic_tts", + type: ModuleRegistry.ModuleType.TTS, + label: "Neuphonic TTS", + }, + openai_tts_python: { + name: "openai_tts_python", + type: ModuleRegistry.ModuleType.TTS, + label: "OpenAI TTS", + }, + dubverse_tts: { + name: "dubverse_tts", + type: ModuleRegistry.ModuleType.TTS, + label: "Dubverse TTS", + }, +}; + +export const v2vModuleRegistry: Record = { + openai_v2v_python: { + name: "openai_v2v_python", + type: ModuleRegistry.ModuleType.V2V, + label: "OpenAI Realtime", + options: { inputModalities: [ModuleRegistry.Modalities.Audio] }, + }, + gemini_v2v_python: { + name: "gemini_v2v_python", + type: ModuleRegistry.ModuleType.V2V, + label: "Gemini Realtime", + options: { + inputModalities: [ + ModuleRegistry.Modalities.Video, + ModuleRegistry.Modalities.Audio, + ], + }, + }, + glm_v2v_python: { + name: "glm_v2v_python", + type: ModuleRegistry.ModuleType.V2V, + label: "GLM Realtime", + options: { inputModalities: [ModuleRegistry.Modalities.Audio] }, + }, + stepfun_v2v_python: { + name: "stepfun_v2v_python", + type: ModuleRegistry.ModuleType.V2V, + label: "Stepfun Realtime", + options: { inputModalities: [ModuleRegistry.Modalities.Audio] }, + }, + azure_v2v_python: { + name: "azure_v2v_python", + type: ModuleRegistry.ModuleType.V2V, + label: "Azure Realtime", + options: { inputModalities: [ModuleRegistry.Modalities.Audio] }, + }, +}; + +export const toolModuleRegistry: Record = { + vision_analyze_tool_python: { + name: "vision_analyze_tool_python", + type: ModuleRegistry.ModuleType.TOOL, + label: "Vision Analyze Tool", + options: {}, + }, + weatherapi_tool_python: { + name: "weatherapi_tool_python", + type: ModuleRegistry.ModuleType.TOOL, + label: "WeatherAPI Tool", + options: {}, + }, + bingsearch_tool_python: { + name: "bingsearch_tool_python", + type: ModuleRegistry.ModuleType.TOOL, + label: "BingSearch Tool", + options: {}, + }, + vision_tool_python: { + name: "vision_tool_python", + type: ModuleRegistry.ModuleType.TOOL, + label: "Vision Tool", + options: {}, + }, + openai_image_generate_tool: { + name: "openai_image_generate_tool", + type: ModuleRegistry.ModuleType.TOOL, + label: "OpenAI Image Generate Tool", + options: { outputContentText: true }, + }, + computer_tool_python: { + name: "computer_tool_python", + type: ModuleRegistry.ModuleType.TOOL, + label: "Computer Tool", + options: { outputContentText: true }, + }, + mcp_client_python: { + name: "mcp_client_python", + type: ModuleRegistry.ModuleType.TOOL, + label: "MCP Client Tool", + options: {}, + }, +}; + +export const moduleRegistry: Record = { + ...sttModuleRegistry, + ...llmModuleRegistry, + ...ttsModuleRegistry, + ...v2vModuleRegistry, +}; + +export const compatibleTools: Record = { + openai_chatgpt_python: [ + "vision_tool_python", + "weatherapi_tool_python", + "bingsearch_tool_python", + "openai_image_generate_tool", + "computer_tool_python", + "mcp_client_python", + ], + openai_v2v_python: [ + "weatherapi_tool_python", + "bingsearch_tool_python", + "openai_image_generate_tool", + "computer_tool_python", + "mcp_client_python", + ], + gemini_v2v_python: [ + "weatherapi_tool_python", + "bingsearch_tool_python", + "openai_image_generate_tool", + "computer_tool_python", + ], + glm_v2v_python: [ + "weatherapi_tool_python", + "bingsearch_tool_python", + "openai_image_generate_tool", + "computer_tool_python", + ], + stepfun_v2v_python: [ + "weatherapi_tool_python", + "bingsearch_tool_python", + "openai_image_generate_tool", + "computer_tool_python", + "mcp_client_python", + ], + azure_v2v_python: [ + "weatherapi_tool_python", + "bingsearch_tool_python", + "openai_image_generate_tool", + "computer_tool_python", + "mcp_client_python", + ], +}; diff --git a/ai_agents/agents/examples/doodler/frontend/src/common/request.ts b/ai_agents/agents/examples/doodler/frontend/src/common/request.ts new file mode 100644 index 0000000000..dab09d1eef --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/common/request.ts @@ -0,0 +1,526 @@ +import axios from "axios"; +import type { Language } from "@/types"; +import { isEditModeOn } from "./constant"; +import { + type AddonDef, + type Connection, + type Graph, + GraphEditor, + type Node, + type ProtocolLabel, +} from "./graph"; +import { genUUID } from "./utils"; + +interface StartRequestConfig { + channel: string; + userId: number; + graphName: string; + language: Language; + voiceType: "male" | "female"; +} + +interface GenAgoraDataConfig { + userId: string | number; + channel: string; +} + +export const apiGenAgoraData = async (config: GenAgoraDataConfig) => { + // the request will be rewrite at middleware.tsx to send to $AGENT_SERVER_URL + const url = `/api/token/generate`; + const { userId, channel } = config; + const data = { + request_id: genUUID(), + uid: userId, + channel_name: channel, + }; + let resp: any = await axios.post(url, data); + resp = resp.data || {}; + return resp; +}; + +export const apiStartService = async ( + config: StartRequestConfig +): Promise => { + // look at app/apis/route.tsx for the server-side implementation + const url = `/api/agents/start`; + const { channel, userId, graphName, language, voiceType } = config; + const data = { + request_id: genUUID(), + channel_name: channel, + user_uid: userId, + graph_name: graphName, + language, + voice_type: voiceType, + }; + let resp: any = await axios.post(url, data); + resp = resp.data || {}; + return resp; +}; + +export const apiStopService = async (channel: string) => { + // the request will be rewrite at middleware.tsx to send to $AGENT_SERVER_URL + const url = `/api/agents/stop`; + const data = { + request_id: genUUID(), + channel_name: channel, + }; + let resp: any = await axios.post(url, data); + resp = resp.data || {}; + return resp; +}; + +export const apiGetDocumentList = async () => { + // the request will be rewrite at middleware.tsx to send to $AGENT_SERVER_URL + const url = `/api/vector/document/preset/list`; + let resp: any = await axios.get(url); + resp = resp.data || {}; + if (resp.code !== "0") { + throw new Error(resp.msg); + } + return resp; +}; + +export const apiUpdateDocument = async (options: { + channel: string; + collection: string; + fileName: string; +}) => { + // the request will be rewrite at middleware.tsx to send to $AGENT_SERVER_URL + const url = `/api/vector/document/update`; + const { channel, collection, fileName } = options; + const data = { + request_id: genUUID(), + channel_name: channel, + collection: collection, + file_name: fileName, + }; + let resp: any = await axios.post(url, data); + resp = resp.data || {}; + return resp; +}; + +// ping/pong +export const apiPing = async (channel: string) => { + // the request will be rewrite at middleware.tsx to send to $AGENT_SERVER_URL + const url = `/api/agents/ping`; + const data = { + request_id: genUUID(), + channel_name: channel, + }; + let resp: any = await axios.post(url, data); + resp = resp.data || {}; + return resp; +}; + +export const apiFetchAddonsExtensions = async (): Promise< + AddonDef.Module[] +> => { + // let resp: any = await axios.get(`/api/dev/v1/addons/extensions`) + const resp: any = await axios.post(`/api/dev/v1/apps/addons`, { + base_dir: ".", + }); + return resp.data.data; +}; + +export const apiCheckCompatibleMessages = async (payload: { + app: string; + graph: string; + extension_group: string; + extension: string; + msg_type: string; + msg_direction: string; + msg_name: string; +}) => { + let resp: any = await axios.post(`/api/dev/v1/messages/compatible`, payload); + resp = resp.data || {}; + return resp; +}; + +export const apiFetchGraphs = async (): Promise => { + if (isEditModeOn) { + const resp: any = await axios.post(`/api/dev/v1/graphs`, {}); + return resp.data.data.map((graph: any) => ({ + name: graph.name, + graph_id: graph.graph_id, + autoStart: graph.auto_start, + nodes: [], + connections: [], + })); + } else { + const resp: any = await axios.get(`/api/agents/graphs`); + return resp.data.data.map((graph: any) => ({ + name: graph.name, + graph_id: graph.graph_id, + autoStart: graph.auto_start, + nodes: [], + connections: [], + })); + } +}; + +export const apiLoadApp = async (): Promise => { + const resp: any = await axios.post(`/api/dev/v1/apps/load`, { + base_dir: ".", + }); + return resp.data.data; +}; + +export const apiFetchGraphNodes = async (graphId: string): Promise => { + // let resp: any = await axios.get(`/api/dev/v1/graphs/${graphId}/nodes`) + const resp: any = await axios.post(`/api/dev/v1/graphs/nodes`, { + graph_id: graphId, + }); + return resp.data.data.map((node: any) => ({ + name: node.name, + addon: node.addon, + extensionGroup: node.extension_group, + app: node.app, + property: node.property || {}, + })); +}; + +export const apiFetchGraphConnections = async ( + graphId: string +): Promise => { + // let resp: any = await axios.get(`/api/dev/v1/graphs/${graphId}/connections`) + const resp: any = await axios.post(`/api/dev/v1/graphs/connections`, { + graph_id: graphId, + }); + return resp.data.data.map((connection: any) => ({ + app: connection.app, + extensionGroup: connection.extension_group, + extension: connection.extension, + cmd: connection.cmd?.map((cmd: any) => ({ + name: cmd.name, + dest: cmd.dest.map((dest: any) => ({ + app: dest.app, + extensionGroup: dest.extension_group, + extension: dest.extension, + msgConversion: dest.msgConversion + ? { + type: dest.msgConversion.type, + rules: dest.msgConversion.rules.map((rule: any) => ({ + path: rule.path, + conversionMode: rule.conversionMode, + value: rule.value, + originalPath: rule.originalPath, + })), + keepOriginal: dest.msgConversion.keepOriginal, + } + : undefined, + })), + })), + data: connection.data?.map((data: any) => ({ + name: data.name, + dest: data.dest.map((dest: any) => ({ + app: dest.app, + extensionGroup: dest.extension_group, + extension: dest.extension, + msgConversion: dest.msgConversion + ? { + type: dest.msgConversion.type, + rules: dest.msgConversion.rules.map((rule: any) => ({ + path: rule.path, + conversionMode: rule.conversionMode, + value: rule.value, + originalPath: rule.originalPath, + })), + keepOriginal: dest.msgConversion.keepOriginal, + } + : undefined, + })), + })), + audio_frame: connection.audio_frame?.map((audioFrame: any) => ({ + name: audioFrame.name, + dest: audioFrame.dest.map((dest: any) => ({ + app: dest.app, + extensionGroup: dest.extension_group, + extension: dest.extension, + msgConversion: dest.msgConversion + ? { + type: dest.msgConversion.type, + rules: dest.msgConversion.rules.map((rule: any) => ({ + path: rule.path, + conversionMode: rule.conversionMode, + value: rule.value, + originalPath: rule.originalPath, + })), + keepOriginal: dest.msgConversion.keepOriginal, + } + : undefined, + })), + })), + video_frame: connection.video_frame?.map((videoFrame: any) => ({ + name: videoFrame.name, + dest: videoFrame.dest.map((dest: any) => ({ + app: dest.app, + extensionGroup: dest.extension_group, + extension: dest.extension, + msgConversion: dest.msgConversion + ? { + type: dest.msgConversion.type, + rules: dest.msgConversion.rules.map((rule: any) => ({ + path: rule.path, + conversionMode: rule.conversionMode, + value: rule.value, + originalPath: rule.originalPath, + })), + keepOriginal: dest.msgConversion.keepOriginal, + } + : undefined, + })), + })), + })); +}; + +export const apiGetDefaultProperty = async (module: string): Promise => { + const resp: any = await axios.post(`/api/dev/v1/extensions/property/get`, { + addon_name: module, + base_dir: ".", + }); + return resp.data.data; +}; + +export const apiAddNode = async ( + graphId: string, + name: string, + module: string, + properties: Record +) => { + const resp: any = await axios.post(`/api/dev/v1/graphs/nodes/add`, { + graph_id: graphId, + name, + addon: module, + property: properties, + }); + return resp.data.data; +}; + +export const apiReplaceNodeModule = async ( + graphId: string, + name: string, + module: string, + properties: Record +) => { + const resp: any = await axios.post(`/api/dev/v1/graphs/nodes/replace`, { + graph_id: graphId, + name, + addon: module, + property: properties, + }); + return resp.data.data; +}; + +export const apiRemoveNode = async ( + graphId: string, + name: string, + module: string +) => { + const resp: any = await axios.post(`/api/dev/v1/graphs/nodes/delete`, { + graph_id: graphId, + name, + addon: module, + }); + return resp.data.data; +}; + +export const apiAddConnection = async ( + graphId: string, + srcExtension: string, + msgType: ProtocolLabel, + msgName: string, + dest_extension: string +) => { + const resp: any = await axios.post(`/api/dev/v1/graphs/connections/add`, { + graph_id: graphId, + src_extension: srcExtension, + msg_type: msgType, + msg_name: msgName, + dest_extension: dest_extension, + }); + return resp.data.data; +}; + +export const apiRemoveConnection = async ( + graphId: string, + srcExtension: string, + msgType: ProtocolLabel, + msgName: string, + dest_extension: string +) => { + const resp: any = await axios.post(`/api/dev/v1/graphs/connections/delete`, { + graph_id: graphId, + src_extension: srcExtension, + msg_type: msgType, + msg_name: msgName, + dest_extension: dest_extension, + }); + return resp.data.data; +}; + +export const apiUpdateGraph = async ( + graphId: string, + updates: Partial +) => { + const { autoStart, nodes, connections } = updates; + const payload: any = {}; + + // Map autoStart field + if (autoStart !== undefined) payload.auto_start = autoStart; + + // Map nodes to the payload + if (nodes) { + payload.nodes = nodes.map((node) => ({ + name: node.name, + addon: node.addon, + extension_group: node.extensionGroup, + app: node.app, + property: node.property, + })); + } + + // Map connections to the payload + if (connections) { + payload.connections = connections.map((connection) => ({ + app: connection.app, + extension: connection.extension, + cmd: connection.cmd?.map((cmd) => ({ + name: cmd.name, + dest: cmd.dest.map((dest) => ({ + app: dest.app, + extension: dest.extension, + msgConversion: dest.msgConversion + ? { + type: dest.msgConversion.type, + rules: dest.msgConversion.rules.map((rule) => ({ + path: rule.path, + conversionMode: rule.conversionMode, + value: rule.value, + originalPath: rule.originalPath, + })), + keepOriginal: dest.msgConversion.keepOriginal, + } + : undefined, + })), + })), + data: connection.data?.map((data) => ({ + name: data.name, + dest: data.dest.map((dest) => ({ + app: dest.app, + extension: dest.extension, + msgConversion: dest.msgConversion + ? { + type: dest.msgConversion.type, + rules: dest.msgConversion.rules.map((rule) => ({ + path: rule.path, + conversionMode: rule.conversionMode, + value: rule.value, + originalPath: rule.originalPath, + })), + keepOriginal: dest.msgConversion.keepOriginal, + } + : undefined, + })), + })), + audio_frame: connection.audio_frame?.map((audioFrame) => ({ + name: audioFrame.name, + dest: audioFrame.dest.map((dest) => ({ + app: dest.app, + extension: dest.extension, + msgConversion: dest.msgConversion + ? { + type: dest.msgConversion.type, + rules: dest.msgConversion.rules.map((rule) => ({ + path: rule.path, + conversionMode: rule.conversionMode, + value: rule.value, + originalPath: rule.originalPath, + })), + keepOriginal: dest.msgConversion.keepOriginal, + } + : undefined, + })), + })), + video_frame: connection.video_frame?.map((videoFrame) => ({ + name: videoFrame.name, + dest: videoFrame.dest.map((dest) => ({ + app: dest.app, + extension: dest.extension, + msgConversion: dest.msgConversion + ? { + type: dest.msgConversion.type, + rules: dest.msgConversion.rules.map((rule) => ({ + path: rule.path, + conversionMode: rule.conversionMode, + value: rule.value, + originalPath: rule.originalPath, + })), + keepOriginal: dest.msgConversion.keepOriginal, + } + : undefined, + })), + })), + })); + } + + // let resp: any = await axios.put(`/api/dev/v1/graphs/${graphId}`, payload) + let resp: any = await axios.post(`/api/dev/v1/graphs/update`, { + graph_id: graphId, + nodes: payload.nodes, + connections: payload.connections, + }); + resp = resp.data || {}; + return resp; +}; + +export const apiFetchAddonModulesDefaultProperties = async (): Promise< + Record> +> => { + const resp: any = await axios.get(`/api/dev/v1/addons/default-properties`); + const properties = resp.data.data; + const result: Record> = {}; + for (const property of properties) { + result[property.addon] = property.property; + } + return result; +}; + +export const apiSaveProperty = async () => { + let resp: any = await axios.put(`/api/dev/v1/property`); + resp = resp.data || {}; + return resp; +}; + +export const apiReloadPackage = async () => { + let resp: any = await axios.post(`/api/dev/v1/apps/reload`, { + base_dir: ".", + }); + resp = resp.data || {}; + return resp; +}; + +export const apiFetchInstalledAddons = async (): Promise => { + const [modules, defaultProperties] = await Promise.all([ + apiFetchAddonsExtensions(), + apiFetchAddonModulesDefaultProperties(), + ]); + return modules.map((module: any) => ({ + name: module.name, + defaultProperty: defaultProperties[module.name], + api: module.api, + })); +}; + +export const apiFetchGraphDetails = async (graph: Graph): Promise => { + const [nodes, connections] = await Promise.all([ + apiFetchGraphNodes(graph.graph_id), + apiFetchGraphConnections(graph.graph_id), + ]); + return { + graph_id: graph.graph_id, + name: graph.name, + autoStart: graph.autoStart, + nodes, + connections, + }; +}; diff --git a/ai_agents/agents/examples/doodler/frontend/src/common/storage.ts b/ai_agents/agents/examples/doodler/frontend/src/common/storage.ts new file mode 100644 index 0000000000..17477453df --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/common/storage.ts @@ -0,0 +1,39 @@ +import type { IOptions, ITrulienceSettings } from "@/types"; +import { + DEFAULT_OPTIONS, + DEFAULT_TRULIENCE_OPTIONS, + OPTIONS_KEY, + TRULIENCE_SETTINGS_KEY, +} from "./constant"; + +export const getOptionsFromLocal = () => { + if (typeof window !== "undefined") { + const data = localStorage.getItem(OPTIONS_KEY); + if (data) { + return JSON.parse(data); + } + } + return DEFAULT_OPTIONS; +}; + +export const setOptionsToLocal = (options: IOptions) => { + if (typeof window !== "undefined") { + localStorage.setItem(OPTIONS_KEY, JSON.stringify(options)); + } +}; + +export const getTrulienceSettingsFromLocal = () => { + if (typeof window !== "undefined") { + const data = localStorage.getItem(TRULIENCE_SETTINGS_KEY); + if (data) { + return JSON.parse(data); + } + } + return DEFAULT_TRULIENCE_OPTIONS; +}; + +export const setTrulienceSettingsToLocal = (settings: ITrulienceSettings) => { + if (typeof window !== "undefined") { + localStorage.setItem(TRULIENCE_SETTINGS_KEY, JSON.stringify(settings)); + } +}; diff --git a/ai_agents/agents/examples/doodler/frontend/src/common/utils.ts b/ai_agents/agents/examples/doodler/frontend/src/common/utils.ts new file mode 100644 index 0000000000..7d050c48f6 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/common/utils.ts @@ -0,0 +1,103 @@ +"use client"; + +import { useEffect, useState } from "react"; + +export const genRandomString = (length: number = 10) => { + let result = ""; + const characters = "abcdefghijklmnopqrstuvwxyz0123456789"; + const charactersLength = characters.length; + + for (let i = 0; i < length; i++) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + } + + return result; +}; + +export const getRandomUserId = (): number => { + return Math.floor(Math.random() * 99999) + 100000; +}; + +export const getRandomChannel = (number = 6) => { + return "agora_" + genRandomString(number); +}; + +export const sleep = (ms: number) => { + return new Promise((resolve) => setTimeout(resolve, ms)); +}; + +export const normalizeFrequencies = (frequencies: Float32Array) => { + const normalizeDb = (value: number) => { + const minDb = -100; + const maxDb = -10; + let db = 1 - (Math.max(minDb, Math.min(maxDb, value)) * -1) / 100; + db = Math.sqrt(db); + + return db; + }; + + // Normalize all frequency values + return frequencies.map((value) => { + if (value === -Infinity) { + return 0; + } + return normalizeDb(value); + }); +}; + +export const genUUID = () => { + return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => { + const r = (Math.random() * 16) | 0; + const v = c === "x" ? r : (r & 0x3) | 0x8; + return v.toString(16); + }); +}; + +export const isMobile = () => { + return /Mobile|iPhone|iPad|Android|Windows Phone/i.test(navigator.userAgent); +}; + +export function useIsCompactLayout(): boolean { + const [isCompactLayout, setIsCompactLayout] = useState(false); + + useEffect(() => { + // Guard clause for SSR or environments without window + if (typeof window === "undefined") { + return; + } + + // Create a media query for max-width: 768px + const mediaQuery = window.matchMedia("(max-width: 768px)"); + + // Set initial value based on the current match state + setIsCompactLayout(mediaQuery.matches); + + // Handler to update state whenever the media query match status changes + const handleChange = (event: MediaQueryListEvent) => { + setIsCompactLayout(event.matches); + }; + + // Attach the listener using the modern API + mediaQuery.addEventListener("change", handleChange); + + // Cleanup + return () => { + mediaQuery.removeEventListener("change", handleChange); + }; + }, []); + + return isCompactLayout; +} + +export const deepMerge = ( + target: Record, + source: Record +): Record => { + for (const key of Object.keys(source)) { + if (source[key] instanceof Object && key in target) { + Object.assign(source[key], deepMerge(target[key], source[key])); + } + } + // Merge source into target + return { ...target, ...source }; +}; diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Agent/AudioVisualizer.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Agent/AudioVisualizer.tsx new file mode 100644 index 0000000000..661ee65005 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Agent/AudioVisualizer.tsx @@ -0,0 +1,52 @@ +export interface AudioVisualizerProps { + type: "agent" | "user"; + frequencies: Float32Array[]; + gap: number; + barWidth: number; + minBarHeight: number; + maxBarHeight: number; + borderRadius: number; +} + +export default function AudioVisualizer(props: AudioVisualizerProps) { + const { + frequencies, + gap, + barWidth, + minBarHeight, + maxBarHeight, + borderRadius, + type, + } = props; + + const summedFrequencies = frequencies.map((bandFrequencies) => { + const sum = bandFrequencies.reduce((a, b) => a + b, 0); + if (sum <= 0) { + return 0; + } + return Math.sqrt(sum / bandFrequencies.length); + }); + + return ( +
+ {summedFrequencies.map((frequency, index) => { + const style = { + height: + minBarHeight + frequency * (maxBarHeight - minBarHeight) + "px", + borderRadius: borderRadius + "px", + width: barWidth + "px", + transition: + "background-color 0.35s ease-out, transform 0.25s ease-out", + // transform: transform, + backgroundColor: type === "agent" ? "#0888FF" : "#EAECF0", + boxShadow: type === "agent" ? "0 0 10px #EAECF0" : "none", + }; + + return ; + })} +
+ ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Agent/AvatarTrulience.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Agent/AvatarTrulience.tsx new file mode 100644 index 0000000000..e720f3cc37 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Agent/AvatarTrulience.tsx @@ -0,0 +1,154 @@ +"use client"; + +import { TrulienceAvatar } from "@trulience/react-sdk"; +import type { IMicrophoneAudioTrack, IRemoteAudioTrack } from "agora-rtc-sdk-ng"; +import { Maximize, Minimize } from "lucide-react"; +import React, { useEffect, useMemo, useRef, useState } from "react"; +import { toast } from "sonner"; +import { useAppSelector } from "@/common"; +import { cn } from "@/lib/utils"; +import { Progress, ProgressIndicator } from "../ui/progress"; + +interface AvatarProps { + audioTrack?: IMicrophoneAudioTrack | IRemoteAudioTrack; + localAudioTrack?: IMicrophoneAudioTrack; +} + +export default function Avatar({ audioTrack }: AvatarProps) { + const agentConnected = useAppSelector((state) => state.global.agentConnected); + const trulienceSettings = useAppSelector( + (state) => state.global.trulienceSettings + ); + const trulienceAvatarRef = useRef(null); + const [errorMessage, setErrorMessage] = useState(""); + + // Track loading progress + const [loadProgress, setLoadProgress] = useState(0); + + // State for the final avatar ID + const [finalAvatarId, setFinalAvatarId] = useState(""); + + // State for toggling fullscreen + const [fullscreen, setFullscreen] = useState(false); + + // Safely read URL param on the client + useEffect(() => { + if (typeof window !== "undefined") { + const urlParams = new URLSearchParams(window.location.search); + const avatarIdFromURL = urlParams.get("avatarId"); + setFinalAvatarId(avatarIdFromURL || trulienceSettings.avatarId || ""); + } + }, []); + + // Define event callbacks + const eventCallbacks = useMemo(() => { + return { + "auth-success": (resp: string) => { + console.log("Trulience Avatar auth-success:", resp); + }, + "auth-fail": (resp: any) => { + console.log("Trulience Avatar auth-fail:", resp); + setErrorMessage(resp.message); + }, + "websocket-connect": (resp: string) => { + console.log("Trulience Avatar websocket-connect:", resp); + }, + "load-progress": (details: Record) => { + console.log("Trulience Avatar load-progress:", details.progress); + setLoadProgress(details.progress); + }, + }; + }, []); + + // Only create TrulienceAvatar instance once we have a final avatar ID + const trulienceAvatarInstance = useMemo(() => { + if (!finalAvatarId) return null; + return ( + + ); + }, [finalAvatarId, eventCallbacks]); + + // Update the Avatar’s audio stream whenever audioTrack or agentConnected changes + useEffect(() => { + if (trulienceAvatarRef.current) { + if (audioTrack && agentConnected) { + const stream = new MediaStream([audioTrack.getMediaStreamTrack()]); + // trulienceAvatarRef.current.setMediaStream(null) + trulienceAvatarRef.current.setMediaStream(stream); + console.warn("[TrulienceAvatar] MediaStream set:", stream); + } else if (!agentConnected) { + const trulienceObj = trulienceAvatarRef.current.getTrulienceObject(); + trulienceObj?.sendMessageToAvatar( + "" + ); + trulienceObj?.sendMessageToAvatar( + "" + ); + } + } + + // Cleanup: unset media stream + return () => { + // trulienceAvatarRef.current?.setMediaStream(null) + }; + }, [audioTrack, agentConnected]); + + return ( +
+ + + {/* Render the TrulienceAvatar */} + {trulienceAvatarInstance} + + {/* Show a loader overlay while progress < 1 */} + {errorMessage ? ( +
+
{errorMessage}
+
+ ) : ( + loadProgress < 1 && ( +
+ {/* Simple Tailwind spinner */} + + + +
+ ) + )} +
+ ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Agent/Camera.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Agent/Camera.tsx new file mode 100644 index 0000000000..2bb619046d --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Agent/Camera.tsx @@ -0,0 +1,197 @@ +"use client"; + +import AgoraRTC, { + type ICameraVideoTrack, + type ILocalVideoTrack, +} from "agora-rtc-sdk-ng"; +import { MonitorIcon, MonitorXIcon } from "lucide-react"; +import * as React from "react"; +import { VIDEO_SOURCE_OPTIONS, VideoSourceType } from "@/common"; +// import { LocalStreamPlayer } from "../streamPlayer" +// import { useSmallScreen } from "@/common" +import { DeviceSelect } from "@/components/Agent/Microphone"; +import { LocalStreamPlayer } from "@/components/Agent/StreamPlayer"; +// import CamSelect from "./camSelect" +import { CamIconByStatus } from "@/components/Icon"; +import { Button } from "@/components/ui/button"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "../ui/select"; + +export const ScreenIconByStatus = ( + props: React.SVGProps & { active?: boolean; color?: string } +) => { + const { active, color, ...rest } = props; + if (active) { + return ; + } + return ; +}; + +export function VideoDeviceWrapper(props: { + children: React.ReactNode; + title: string; + Icon: ( + props: React.SVGProps & { active?: boolean } + ) => React.ReactNode; + onIconClick: () => void; + videoSourceType: VideoSourceType; + onVideoSourceChange: (value: VideoSourceType) => void; + isActive: boolean; + select?: React.ReactNode; +}) { + const { + Icon, + onIconClick, + isActive, + select, + children, + onVideoSourceChange, + videoSourceType, + } = props; + + return ( +
+
+
+
{props.title}
+
+ +
+
+
+ + {select} +
+
+ {children} +
+ ); +} + +export default function VideoBlock(props: { + videoSourceType: VideoSourceType; + onVideoSourceChange: (value: VideoSourceType) => void; + cameraTrack?: ICameraVideoTrack; + screenTrack?: ILocalVideoTrack; +}) { + const { videoSourceType, cameraTrack, screenTrack, onVideoSourceChange } = + props; + const [videoMute, setVideoMute] = React.useState(false); + + React.useEffect(() => { + cameraTrack?.setMuted(videoMute); + screenTrack?.setMuted(videoMute); + }, [cameraTrack, screenTrack, videoMute]); + + const onClickMute = () => { + setVideoMute(!videoMute); + }; + + return ( + + ) : ( +
+ ) + } + > +
+ +
+ + ); +} + +interface SelectItem { + label: string; + value: string; + deviceId: string; +} + +const DEFAULT_ITEM: SelectItem = { + label: "Default", + value: "default", + deviceId: "", +}; + +const CamSelect = (props: { videoTrack?: ICameraVideoTrack }) => { + const { videoTrack } = props; + const [items, setItems] = React.useState([DEFAULT_ITEM]); + const [value, setValue] = React.useState("default"); + + React.useEffect(() => { + if (videoTrack) { + const label = videoTrack?.getTrackLabel(); + setValue(label); + AgoraRTC.getCameras().then((arr) => { + setItems( + arr.map((item) => ({ + label: item.label, + value: item.label, + deviceId: item.deviceId, + })) + ); + }); + } + }, [videoTrack]); + + const onChange = async (value: string) => { + const target = items.find((item) => item.value === value); + if (target) { + setValue(target.value); + if (videoTrack) { + await videoTrack.setDevice(target.deviceId); + } + } + }; + + return ( + + ); +}; diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Agent/Microphone.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Agent/Microphone.tsx new file mode 100644 index 0000000000..308cc7ea66 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Agent/Microphone.tsx @@ -0,0 +1,179 @@ +"use client"; + +import AgoraRTC, { type IMicrophoneAudioTrack } from "agora-rtc-sdk-ng"; +import * as React from "react"; +import { useMultibandTrackVolume } from "@/common"; +import AudioVisualizer from "@/components/Agent/AudioVisualizer"; +import { MicIconByStatus } from "@/components/Icon"; +import { Button } from "@/components/ui/button"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; + +export default function MicrophoneBlock(props: { + audioTrack?: IMicrophoneAudioTrack; +}) { + const { audioTrack } = props; + const [audioMute, setAudioMute] = React.useState(false); + const [mediaStreamTrack, setMediaStreamTrack] = + React.useState(); + + React.useEffect(() => { + audioTrack?.on("track-updated", onAudioTrackupdated); + if (audioTrack) { + setMediaStreamTrack(audioTrack.getMediaStreamTrack()); + } + + return () => { + audioTrack?.off("track-updated", onAudioTrackupdated); + }; + }, [audioTrack]); + + React.useEffect(() => { + audioTrack?.setMuted(audioMute); + }, [audioTrack, audioMute]); + + const subscribedVolumes = useMultibandTrackVolume(mediaStreamTrack, 20); + + const onAudioTrackupdated = (track: MediaStreamTrack) => { + console.log("[test] audio track updated", track); + setMediaStreamTrack(track); + }; + + const onClickMute = () => { + setAudioMute(!audioMute); + }; + + return ( + } + > +
+ +
+
+ ); +} + +export function CommonDeviceWrapper(props: { + children: React.ReactNode; + title: string; + Icon: ( + props: React.SVGProps & { active?: boolean } + ) => React.ReactNode; + onIconClick: () => void; + isActive: boolean; + select?: React.ReactNode; +}) { + const { title, Icon, onIconClick, isActive, select, children } = props; + + return ( +
+
+
{title}
+
+ + {select} +
+
+ {children} +
+ ); +} + +export type TDeviceSelectItem = { + label: string; + value: string; + deviceId: string; +}; + +export const DEFAULT_DEVICE_ITEM: TDeviceSelectItem = { + label: "Default", + value: "default", + deviceId: "", +}; + +export const DeviceSelect = (props: { + items: TDeviceSelectItem[]; + value: string; + onChange: (value: string) => void; + placeholder?: string; +}) => { + const { items, value, onChange, placeholder } = props; + + return ( + + ); +}; + +export const MicrophoneSelect = (props: { + audioTrack?: IMicrophoneAudioTrack; +}) => { + const { audioTrack } = props; + const [items, setItems] = React.useState([ + DEFAULT_DEVICE_ITEM, + ]); + const [value, setValue] = React.useState("default"); + + React.useEffect(() => { + if (audioTrack) { + const label = audioTrack?.getTrackLabel(); + setValue(label); + AgoraRTC.getMicrophones().then((arr) => { + setItems( + arr.map((item) => ({ + label: item.label, + value: item.label, + deviceId: item.deviceId, + })) + ); + }); + } + }, [audioTrack]); + + const onChange = async (value: string) => { + const target = items.find((item) => item.value === value); + if (target) { + setValue(target.value); + if (audioTrack) { + await audioTrack.setDevice(target.deviceId); + } + } + }; + + return ; +}; diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Agent/StreamPlayer.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Agent/StreamPlayer.tsx new file mode 100644 index 0000000000..d1246d46fb --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Agent/StreamPlayer.tsx @@ -0,0 +1,59 @@ +"use client"; + +import type { + ICameraVideoTrack, + ILocalVideoTrack, + IMicrophoneAudioTrack, + VideoPlayerConfig, +} from "agora-rtc-sdk-ng"; +import * as React from "react"; + +export interface StreamPlayerProps { + videoTrack?: ICameraVideoTrack | ILocalVideoTrack; + audioTrack?: IMicrophoneAudioTrack; + style?: React.CSSProperties; + fit?: "cover" | "contain" | "fill"; + onClick?: () => void; + mute?: boolean; +} + +export const LocalStreamPlayer = React.forwardRef( + (props: StreamPlayerProps, ref) => { + const { + videoTrack, + audioTrack, + mute = false, + style = {}, + fit = "cover", + onClick = () => {}, + } = props; + const vidDiv = React.useRef(null); + + React.useLayoutEffect(() => { + const config = { fit } as VideoPlayerConfig; + if (mute) { + videoTrack?.stop(); + } else { + if (!videoTrack?.isPlaying) { + videoTrack?.play(vidDiv.current!, config); + } + } + + return () => { + videoTrack?.stop(); + }; + }, [videoTrack, fit, mute]); + + // local audio track need not to be played + // useLayoutEffect(() => {}, [audioTrack, localAudioMute]) + + return ( +
+ ); + } +); diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Agent/View.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Agent/View.tsx new file mode 100644 index 0000000000..4515448d32 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Agent/View.tsx @@ -0,0 +1,62 @@ +"use client"; + +// import AudioVisualizer from "../audioVisualizer" +import type { IMicrophoneAudioTrack, IRemoteAudioTrack, IRemoteVideoTrack } from "agora-rtc-sdk-ng"; +import { useEffect } from "react"; +import { useMultibandTrackVolume } from "@/common"; +import AudioVisualizer from "@/components/Agent/AudioVisualizer"; +import { cn } from "@/lib/utils"; + +export interface AgentViewProps { + audioTrack?: IRemoteAudioTrack; + videoTrack?: IRemoteVideoTrack; +} + +export default function AgentView(props: AgentViewProps) { + const { audioTrack, videoTrack } = props; + + const subscribedVolumes = useMultibandTrackVolume(audioTrack, 12); + + useEffect(() => { + if (videoTrack) { + const currentTrack = videoTrack; + currentTrack.play(`remote-video-${currentTrack.getUserId()}`, { fit: "cover" }); + + return () => { + currentTrack.stop(); + }; + } + }, [videoTrack?.getUserId()]); + + return ( + videoTrack ? ( +
+
+ ) : ( +
+
Agent
+
+ +
+
+ ) + ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Agent/VoicePresetSelect.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Agent/VoicePresetSelect.tsx new file mode 100644 index 0000000000..c0fbfeefb3 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Agent/VoicePresetSelect.tsx @@ -0,0 +1,47 @@ +"use client"; + +import { useAppDispatch, useAppSelector, VOICE_OPTIONS } from "@/common"; +import { VoiceIcon } from "@/components/Icon"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { setVoiceType } from "@/store/reducers/global"; +import type { VoiceType } from "@/types"; + +export default function AgentVoicePresetSelect() { + const dispatch = useAppDispatch(); + const options = useAppSelector((state) => state.global.options); + const voiceType = useAppSelector((state) => state.global.voiceType); + + const onVoiceChange = (value: string) => { + dispatch(setVoiceType(value as VoiceType)); + }; + + return ( + + ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Button/LoadingButton.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Button/LoadingButton.tsx new file mode 100644 index 0000000000..23e6457212 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Button/LoadingButton.tsx @@ -0,0 +1,17 @@ +import { AnimatedSpinnerIcon } from "@/components/Icon"; +import { Button, type ButtonProps } from "@/components/ui/button"; + +export interface LoadingButtonProps extends Omit { + loading?: boolean; + svgProps?: React.SVGProps; +} + +export function LoadingButton(props: LoadingButtonProps) { + const { loading, disabled, children, svgProps, ...rest } = props; + return ( + + ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Chat/ChatCard.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Chat/ChatCard.tsx new file mode 100644 index 0000000000..8b1f0de525 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Chat/ChatCard.tsx @@ -0,0 +1,145 @@ +"use client"; + +import { Send } from "lucide-react"; +import * as React from "react"; +import { useAppDispatch, useAppSelector, useAutoScroll } from "@/common"; +import MessageList from "@/components/Chat/MessageList"; +import { Button } from "@/components/ui/button"; +import { cn } from "@/lib/utils"; +import { rtmManager } from "@/manager/rtm"; +import { addChatItem } from "@/store/reducers/global"; +import { + EMessageDataType, + EMessageType, + ERTMTextType, + type IRTMTextItem, +} from "@/types"; + +export default function ChatCard(props: { className?: string }) { + const { className } = props; + const [modal2Open, setModal2Open] = React.useState(false); + const [inputValue, setInputValue] = React.useState(""); + + const rtmConnected = useAppSelector((state) => state.global.rtmConnected); + const dispatch = useAppDispatch(); + const graphName = useAppSelector((state) => state.global.selectedGraphId); + const agentConnected = useAppSelector((state) => state.global.agentConnected); + const options = useAppSelector((state) => state.global.options); + + const disableInputMemo = React.useMemo(() => { + return ( + !options.channel || + !options.userId || + !options.appId || + !options.token || + !rtmConnected || + !agentConnected + ); + }, [ + options.channel, + options.userId, + options.appId, + options.token, + rtmConnected, + agentConnected, + ]); + + // const chatItems = genRandomChatList(10) + const chatRef = React.useRef(null); + + useAutoScroll(chatRef); + + const onTextChanged = (text: IRTMTextItem) => { + console.log("[rtm] onTextChanged", text); + if (text.type == ERTMTextType.TRANSCRIBE) { + // const isAgent = Number(text.uid) != Number(options.userId) + dispatch( + addChatItem({ + userId: options.userId, + text: text.text, + type: text.stream_id === "0" ? EMessageType.AGENT : EMessageType.USER, + data_type: EMessageDataType.TEXT, + isFinal: text.is_final, + time: text.ts, + }) + ); + } + if (text.type == ERTMTextType.INPUT_TEXT) { + dispatch( + addChatItem({ + userId: options.userId, + text: text.text, + type: EMessageType.USER, + data_type: EMessageDataType.TEXT, + isFinal: true, + time: text.ts, + }) + ); + } + }; + + const handleInputChange = (e: React.ChangeEvent) => { + setInputValue(e.target.value); + }; + + const handleInputSubmit = (e: React.FormEvent) => { + e.preventDefault(); + if (!inputValue || disableInputMemo) { + return; + } + rtmManager.sendText(inputValue); + setInputValue(""); + }; + + return ( + <> + {/* Chat Card */} +
+
+ {/* Scrollable messages container */} +
+ +
+ {/* Input area */} +
+
+ + +
+
+
+
+ + ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Chat/ChatCfgGraphSelect.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Chat/ChatCfgGraphSelect.tsx new file mode 100644 index 0000000000..ca6d37572e --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Chat/ChatCfgGraphSelect.tsx @@ -0,0 +1,64 @@ +import * as React from "react"; +import { useIsCompactLayout } from "@/common"; +import { useAppDispatch, useAppSelector } from "@/common/hooks"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { cn } from "@/lib/utils"; +import { setSelectedGraphId } from "@/store/reducers/global"; + +export function RemoteGraphSelect() { + const dispatch = useAppDispatch(); + const graphName = useAppSelector((state) => state.global.selectedGraphId); + const graphs = useAppSelector((state) => state.global.graphList); + const agentConnected = useAppSelector((state) => state.global.agentConnected); + + const onGraphNameChange = (val: string) => { + dispatch(setSelectedGraphId(val)); + }; + + const graphOptions = graphs.map((item) => ({ + label: item.name, + value: item.graph_id, + })); + + // Get the selected graph's label for display + const selectedGraph = graphs.find((g) => g.graph_id === graphName); + const displayLabel = selectedGraph?.name || "Select Graph"; + + // Truncate label for display when closed (max 20 chars on mobile, 25 on desktop) + const truncatedLabel = displayLabel.length > 20 + ? displayLabel.substring(0, 17) + "..." + : displayLabel; + + return ( + <> + + + ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Chat/ChatCfgModuleSelect.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Chat/ChatCfgModuleSelect.tsx new file mode 100644 index 0000000000..eeb00f236f --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Chat/ChatCfgModuleSelect.tsx @@ -0,0 +1,540 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { + BoxesIcon, + ChevronRightIcon, + LoaderCircleIcon, + Trash2Icon, + WrenchIcon, +} from "lucide-react"; +import * as React from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; +import { + apiAddConnection, + apiAddNode, + apiGetDefaultProperty, + apiRemoveNode, + apiReplaceNodeModule, + isLLM, +} from "@/common"; +import { + AddonDef, + Destination, + type Graph, + ProtocolLabel as GraphConnProtocol, + GraphEditor, + ProtocolLabel, +} from "@/common/graph"; +import { useAppSelector, useGraphs } from "@/common/hooks"; +import { + compatibleTools, + ModuleRegistry, + ModuleTypeLabels, + moduleRegistry, + toolModuleRegistry, +} from "@/common/moduleConfig"; +import { Button, buttonVariants } from "@/components/ui/button"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectLabel, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { + Sheet, + SheetContent, + SheetDescription, + SheetHeader, + SheetTitle, + SheetTrigger, +} from "@/components/ui/sheet"; +import { cn } from "@/lib/utils"; +import { fetchGraphDetails } from "@/store/reducers/global"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuPortal, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuTrigger, +} from "../ui/dropdown"; + +export function RemoteModuleCfgSheet() { + const addonModules = useAppSelector((state) => state.global.addonModules); + const { + getGraphNodeAddonByName, + selectedGraph, + updateGraph, + installedAndRegisteredModulesMap, + installedAndRegisteredToolModules, + } = useGraphs(); + + const metadata = React.useMemo(() => { + const dynamicMetadata: Record< + string, + { type: string; options: { value: string; label: string }[] } + > = {}; + + if (selectedGraph) { + Object.keys(installedAndRegisteredModulesMap).forEach((key) => { + const moduleTypeKey = key as ModuleRegistry.NonToolModuleType; + + // Check if the current graph has a node whose name contains the ModuleType + const hasMatchingNode = selectedGraph.nodes.some((node) => + node.name.includes(moduleTypeKey) + ); + + if (hasMatchingNode) { + dynamicMetadata[moduleTypeKey] = { + type: "string", + options: installedAndRegisteredModulesMap[moduleTypeKey].map( + (module) => ({ + value: module.name, + label: module.label, + }) + ), + }; + } + }); + } + + return dynamicMetadata; + }, [installedAndRegisteredModulesMap, selectedGraph]); + + const initialData = React.useMemo(() => { + const dynamicInitialData: Record = {}; + + if (selectedGraph) { + Object.keys(installedAndRegisteredModulesMap).forEach((key) => { + const moduleTypeKey = key as ModuleRegistry.ModuleType; + + // Check if the current graph has a node whose name contains the ModuleType + const hasMatchingNode = selectedGraph.nodes.some((node) => + node.name.includes(moduleTypeKey) + ); + + if (hasMatchingNode) { + dynamicInitialData[moduleTypeKey] = + getGraphNodeAddonByName(moduleTypeKey)?.addon; + } + }); + } + + return dynamicInitialData; + }, [ + installedAndRegisteredModulesMap, + selectedGraph, + getGraphNodeAddonByName, + ]); + + return ( + + + + + + + Module Picker + + You can adjust STT/TTS/LLM/LLMv2v extension modules here, the values + will be written into property.json file when you save. + + + +
+ { + try { + // Clone the selectedGraph to avoid mutating the original graph + const selectedGraphCopy: Graph = JSON.parse( + JSON.stringify(selectedGraph) + ); + const nodes = selectedGraphCopy.nodes; + let needUpdate = false; + let enableRTCVideoSubscribe = false; + + // Retrieve the agora_rtc node + const agoraRtcNode = GraphEditor.findNode( + selectedGraphCopy, + "agora_rtc" + ); + if (!agoraRtcNode) { + toast.error("agora_rtc node not found in the graph"); + return; + } + + // Update graph nodes with selected modules + Object.entries(data).forEach(([key, value]) => { + const node = nodes.find((n) => n.name === key); + if (node && value && node.addon !== value) { + node.addon = value; + node.property = addonModules.find( + (module) => module.name === value + )?.defaultProperty; + needUpdate = true; + } + }); + + const reasoningNodesWithVisualSupport = + GraphEditor.findNodeByPredicate(selectedGraphCopy, (node) => { + const module = moduleRegistry[node.addon]; + if (!module) { + return false; + } + + if (module.type === ModuleRegistry.ModuleType.LLM) { + const llmModule = module as ModuleRegistry.LLMModule; + return ( + isLLM(node.name) && + llmModule.options.inputModalities.includes( + ModuleRegistry.Modalities.Video + ) + ); + } + + if (module.type === ModuleRegistry.ModuleType.V2V) { + const v2vModule = module as ModuleRegistry.V2VModule; + return ( + isLLM(node.name) && + v2vModule.options.inputModalities.includes( + ModuleRegistry.Modalities.Video + ) + ); + } + + return false; + }); + + if (reasoningNodesWithVisualSupport) { + GraphEditor.addOrUpdateConnection( + selectedGraphCopy, + `${agoraRtcNode.name}`, + `${reasoningNodesWithVisualSupport.name}`, + ProtocolLabel.VIDEO_FRAME, + "video_frame" + ); + enableRTCVideoSubscribe = true; + } + + // Identify removed tools and process them + const currentToolsInGraph = nodes + .filter((node) => + installedAndRegisteredToolModules + .map((module) => module.name) + .includes(node.addon) + ) + .map((node) => node.addon); + + const removedTools = currentToolsInGraph.filter( + (tool) => !tools.includes(tool) + ); + removedTools.forEach((tool) => { + GraphEditor.removeNodeAndConnections(selectedGraphCopy, tool); + needUpdate = true; + }); + + // Process tool modules + if (tools.length > 0) { + if (!enableRTCVideoSubscribe) { + enableRTCVideoSubscribe = tools.some((tool) => + tool.includes("vision") + ); + } + tools.forEach((tool) => { + if (!currentToolsInGraph.includes(tool)) { + const toolModule = addonModules.find( + (module) => module.name === tool + ); + + if (!toolModule) { + toast.error(`Module ${tool} not found`); + return; + } + + const toolNode = GraphEditor.addNode( + selectedGraphCopy, + tool, + tool, + "default", + toolModule.defaultProperty + ); + + // Create or update connections + const llmNode = GraphEditor.findNodeByPredicate( + selectedGraphCopy, + (node) => isLLM(node.name) + ); + if (llmNode) { + GraphEditor.linkTool( + selectedGraphCopy, + llmNode, + toolNode, + toolModuleRegistry[tool] + ); + } + } + }); + needUpdate = true; + } + + GraphEditor.enableRTCVideoSubscribe( + selectedGraphCopy, + enableRTCVideoSubscribe + ); + + // Perform the update if changes are detected + if (needUpdate) { + await updateGraph(selectedGraph, selectedGraphCopy); + toast.success("Modules updated", { + description: `Graph: ${selectedGraphCopy.graph_id}`, + }); + } + } catch (e: any) { + toast.error(`Failed to update modules: ${e}`); + } + }} + /> +
+
+
+ ); +} + +const GraphModuleCfgForm = ({ + initialData, + metadata, + onUpdate, +}: { + initialData: Record; + metadata: Record< + string, + { type: string; options: { value: string; label: string }[] } + >; + onUpdate: (data: Record, tools: string[]) => void; +}) => { + const formSchema = z.record(z.string(), z.string().nullable()); + const form = useForm>({ + resolver: zodResolver(formSchema), + defaultValues: initialData, + }); + const { selectedGraph, installedAndRegisteredToolModules } = useGraphs(); + const { watch } = form; + + // Watch for changes in "llm" and "v2v" fields + const llmValue = watch("llm"); + const v2vValue = watch("v2v"); + const toolModules = React.useMemo(() => { + // Step 1: Get installed and registered tool modules + const allToolModules = installedAndRegisteredToolModules || []; + + // Step 2: Determine the active module based on form values + const activeModule = llmValue || v2vValue; + + // Step 3: Get compatible tools for the active module + if (activeModule) { + const compatibleToolNames = compatibleTools[activeModule] || []; + return allToolModules.filter((module) => + compatibleToolNames.includes(module.name) + ); + } + + // If no LLM or V2V module is selected, return all tool modules + return []; + }, [installedAndRegisteredToolModules, selectedGraph, llmValue, v2vValue]); + + const onSubmit = (data: z.infer) => { + onUpdate(data, selectedTools); + }; + + const [selectedTools, setSelectedTools] = React.useState([]); + + // Synchronize selectedTools with selectedGraph and toolModules + React.useEffect(() => { + const toolNames = toolModules.map((module) => module.name); + const graphToolAddons = + selectedGraph?.nodes + .filter((node) => toolNames.includes(node.addon)) + .map((node) => node.addon) || []; + setSelectedTools(graphToolAddons); + }, [toolModules, selectedGraph]); + + // Desired field order + const fieldOrder: ModuleRegistry.NonToolModuleType[] = [ + ModuleRegistry.ModuleType.STT, + ModuleRegistry.ModuleType.LLM, + ModuleRegistry.ModuleType.V2V, + ModuleRegistry.ModuleType.TTS, + ]; + return ( +
+ + {fieldOrder.map( + (key) => + metadata[key] && ( // Check if the field exists in metadata +
+ ( + + +
+
{ModuleTypeLabels[key]}
+ {isLLM(key) && ( + + + + + + + } + className="flex justify-between" + > + Add Tools + + + + {toolModules.length > 0 ? ( + toolModules.map((module) => ( + { + if ( + !selectedTools.includes( + module.name + ) + ) { + setSelectedTools((prev) => [ + ...prev, + module.name, + ]); + } + }} + > + {module.name} + + )) + ) : ( + + No compatible tools + + )} + + + + + + )} +
+
+ + + +
+ )} + /> + {isLLM(key) && selectedTools.length > 0 && ( +
+ {selectedTools.map((tool) => ( +
+ {tool} +
{ + setSelectedTools((prev) => + prev.filter((t) => t !== tool) + ); + }} // Delete action + > + +
+
+ ))} +
+ )} +
+ ) + )} + + +
+ + ); +}; diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Chat/ChatCfgPropertySelect.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Chat/ChatCfgPropertySelect.tsx new file mode 100644 index 0000000000..d4026de183 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Chat/ChatCfgPropertySelect.tsx @@ -0,0 +1,441 @@ +"use client"; + +import { zodResolver } from "@hookform/resolvers/zod"; +import { + BoxesIcon, + LoaderCircleIcon, + SettingsIcon, + Trash2Icon, +} from "lucide-react"; +import * as React from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; +import { useAppDispatch, useAppSelector } from "@/common"; +import type { AddonDef, Graph } from "@/common/graph"; +import { useGraphs } from "@/common/hooks"; +import { Button, buttonVariants } from "@/components/ui/button"; +import { Checkbox } from "@/components/ui/checkbox"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectLabel, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { + Sheet, + SheetClose, + SheetContent, + SheetDescription, + SheetFooter, + SheetHeader, + SheetTitle, + SheetTrigger, +} from "@/components/ui/sheet"; +import { Switch } from "@/components/ui/switch"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { cn } from "@/lib/utils"; + +export function RemotePropertyCfgSheet() { + const dispatch = useAppDispatch(); + const { selectedGraph, updateGraph } = useGraphs(); + const graphName = useAppSelector((state) => state.global.selectedGraphId); + + const [selectedExtension, setSelectedExtension] = React.useState(""); + const selectedExtensionNode = selectedGraph?.nodes.find( + (n) => n.name === selectedExtension + ); + const addonModules = useAppSelector((state) => state.global.addonModules); + const selectedAddonModule = addonModules.find( + (module) => module.name === selectedExtensionNode?.addon + ); + const hasProperty = + !!selectedAddonModule?.api?.property?.properties && + Object.keys(selectedAddonModule?.api?.property?.properties).length > 0; + + return ( + + + + + + + Properties Setting + + You can adjust extension properties for selected graph here, the + values will be written into property.json file when you save. + + + +
+ + +
+ + {hasProperty ? ( + selectedExtensionNode?.["property"] && ( + module.name === selectedExtensionNode?.addon + )?.api?.property?.properties || {} + } + onUpdate={async (data) => { + // clone the overridenProperties + const selectedGraphCopy: Graph = JSON.parse( + JSON.stringify(selectedGraph) + ); + const nodes = selectedGraphCopy?.nodes || []; + let needUpdate = false; + for (const node of nodes) { + if (node.name === selectedExtension) { + node.property = data; + needUpdate = true; + } + } + if (needUpdate) { + await updateGraph(selectedGraph, selectedGraphCopy); + toast.success("Properties updated", { + description: `Graph: ${graphName}, Extension: ${selectedExtension}`, + }); + } + }} + /> + ) + ) : ( + + No properties found for the selected extension. + + )} +
+
+ ); +} + +export function RemotePropertyAddCfgSheet({ + selectedExtension, + extensionNodeData, + onUpdate, +}: { + selectedExtension: string; + extensionNodeData: Record; + onUpdate: (data: string) => void; +}) { + const dispatch = useAppDispatch(); + const { selectedGraph } = useGraphs(); + + const selectedExtensionNode = selectedGraph?.nodes.find( + (n) => n.name === selectedExtension + ); + const addonModules = useAppSelector((state) => state.global.addonModules); + const selectedAddonModule = addonModules.find( + (module) => module.name === selectedExtensionNode?.addon + ); + const allProperties = Object.keys( + selectedAddonModule?.api?.property?.properties || {} + ); + const usedProperties = Object.keys(extensionNodeData); + const remainingProperties = allProperties.filter( + (prop) => !usedProperties.includes(prop) + ); + const hasRemainingProperties = remainingProperties.length > 0; + + const [selectedProperty, setSelectedProperty] = React.useState(""); + const [isSheetOpen, setSheetOpen] = React.useState(false); // State to control the sheet + + return ( + + +
+ +
+
+ + + Property Add + + You can add a property into a graph extension node and configure its + value. + + + {hasRemainingProperties ? ( + <> + + + + + ) : ( + <> + + No remaining properties to add. + + + + )} + +
+ ); +} + +// Helper to convert values based on type +const convertToType = (value: any, type: string) => { + switch (type) { + case "int64": + case "int32": + return parseInt(value, 10); + case "float64": + case "float32": + return parseFloat(value); + case "bool": + return value === true || value === "true"; + case "string": + return String(value); + default: + return value; + } +}; + +const defaultTypeValue = (type: string) => { + switch (type) { + case "int64": + case "int32": + return 0; + case "float64": + return 0.1; + case "bool": + return false; + case "string": + default: + return ""; + } +}; + +import { useState } from "react"; + +const GraphCfgForm = ({ + selectedExtension, + selectedAddonModule, + initialData, + metadata, + onUpdate, +}: { + selectedExtension: string; + selectedAddonModule: AddonDef.Module | undefined; + initialData: Record; + metadata: Record; + onUpdate: (data: Record) => void; +}) => { + const formSchema = z.record( + z.string(), + z.union([z.string(), z.number(), z.boolean(), z.null()]) + ); + + const [formData, setFormData] = useState(initialData); + + const form = useForm>({ + resolver: zodResolver(formSchema), + defaultValues: formData, + }); + + const onSubmit = (data: z.infer) => { + const convertedData = Object.entries(data).reduce( + (acc, [key, value]) => { + const type = metadata[key]?.type || "string"; + acc[key] = + value === "" ? defaultTypeValue(type) : convertToType(value, type); + return acc; + }, + {} as Record + ); + onUpdate(convertedData); + }; + + const handleDelete = (key: string) => { + const updatedData = { ...formData }; + delete updatedData[key]; // Remove the specific key + setFormData(updatedData); // Update state + form.reset(updatedData); // Reset the form + }; + + const initialDataWithType = Object.entries(formData).reduce( + (acc, [key, value]) => { + acc[key] = { value, type: metadata[key]?.type || "string" }; + return acc; + }, + {} as Record< + string, + { value: string | number | boolean | null; type: string } + > + ); + + return ( +
+ + {Object.entries(initialDataWithType).map(([key, { value, type }]) => ( + ( + + {key} +
+ + {type === "bool" ? ( +
+ +
+ ) : ( + + )} +
+
handleDelete(key)} // Delete action + > + +
+
+
+ )} + /> + ))} +
+ { + const defaultProperty = + selectedAddonModule?.defaultProperty || {}; + let defaultValue = defaultProperty[key]; + + if (defaultValue === undefined) { + const schema = + selectedAddonModule?.api?.property?.properties || {}; + const schemaType = schema[key]?.type; + if (schemaType === "bool") { + defaultValue = false; + } + } + const updatedData = { ...formData }; + updatedData[key] = defaultValue; + setFormData(updatedData); + form.reset(updatedData); + }} + /> + +
+ + + ); +}; diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Chat/ChatCfgTrulienceSetting.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Chat/ChatCfgTrulienceSetting.tsx new file mode 100644 index 0000000000..ab7ed47ba9 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Chat/ChatCfgTrulienceSetting.tsx @@ -0,0 +1,269 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { LoaderCircleIcon, UsersIcon } from "lucide-react"; +import * as React from "react"; +import { set, useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; +import { useAppDispatch, useAppSelector } from "@/common/hooks"; +import { Button, buttonVariants } from "@/components/ui/button"; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, +} from "@/components/ui/form"; +import { + Sheet, + SheetContent, + SheetDescription, + SheetHeader, + SheetTitle, + SheetTrigger, +} from "@/components/ui/sheet"; +import { cn } from "@/lib/utils"; +import { setTrulienceSettings } from "@/store/reducers/global"; +import { Input } from "../ui/input"; +import { Switch } from "../ui/switch"; + +export function TrulienceCfgSheet() { + const dispatch = useAppDispatch(); + const trulienceSettings = useAppSelector( + (state) => state.global.trulienceSettings + ); + return ( + + + + + + + Trulience Avatar + + You can configure the Trulience Avatar settings here. This will give + you a nice avatar for your chat. + + + +
+ { + if (data.enable_trulience_avatar === true) { + if (!data.trulience_avatar_id) { + toast.error("Trulience Settings", { + description: `Please provide Trulience Avatar ID`, + }); + return; + } + } + dispatch( + setTrulienceSettings({ + enabled: data.enable_trulience_avatar as boolean, + avatarId: data.trulience_avatar_id as string, + avatarToken: data.trulience_avatar_token as string, + avatarDesktopLargeWindow: + data.trulience_large_window as boolean, + trulienceSDK: data.trulience_sdk_url as string, + animationURL: data.trulience_animation_url as string, + }) + ); + toast.success("Trulience Settings", { + description: `Settings updated successfully`, + }); + }} + /> +
+
+
+ ); +} + +const TrulienceCfgForm = ({ + initialData, + onUpdate, +}: { + initialData: Record; + onUpdate: (data: Record) => void; +}) => { + const formSchema = z.record( + z.string(), + z.union([z.string(), z.boolean(), z.null()]) + ); + const form = useForm>({ + resolver: zodResolver(formSchema), + defaultValues: initialData, + }); + const { watch } = form; + // Watch for changes in "enable_trulience_avatar" field + const enableTrulienceAvatar = watch("enable_trulience_avatar"); + + const onSubmit = (data: z.infer) => { + onUpdate(data); + }; + return ( +
+ + ( + + Enable Trulience Avatar +
+ +
+ +
+
+
+
+ )} + /> + {enableTrulienceAvatar && ( + <> + ( + + Trulience Avatar ID +
+ + + +
+
+ )} + /> + ( + + Trulience Avatar Token +
+ + + +
+
+ )} + /> + ( + + Trulience Large Window +
+ +
+ +
+
+
+
+ )} + /> + ( + + Trulience SDK URL +
+ + + +
+
+ )} + /> + ( + + Trulience Animation URL +
+ + + +
+
+ )} + /> + + )} + + + + ); +}; diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Chat/MessageList.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Chat/MessageList.tsx new file mode 100644 index 0000000000..f7ce44a3a0 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Chat/MessageList.tsx @@ -0,0 +1,79 @@ +import { Bot, Brain, MessageCircleQuestion } from "lucide-react"; +import * as React from "react"; +import { + GRAPH_OPTIONS, + isRagGraph, + LANGUAGE_OPTIONS, + useAppDispatch, + useAppSelector, + useAutoScroll, +} from "@/common"; +import { Avatar, AvatarFallback } from "@/components/ui/avatar"; +import { cn } from "@/lib/utils"; +import { EMessageDataType, EMessageType, type IChatItem } from "@/types"; + +export default function MessageList(props: { className?: string }) { + const { className } = props; + + const chatItems = useAppSelector((state) => state.global.chatItems); + + const containerRef = React.useRef(null); + + useAutoScroll(containerRef); + + return ( +
+ {chatItems.map((item, index) => { + return ; + })} +
+ ); +} + +export function MessageItem(props: { data: IChatItem }) { + const { data } = props; + + return ( + <> +
+ {data.type === EMessageType.AGENT ? ( + data.data_type === EMessageDataType.REASON ? ( + + + + + + ) : ( + + + + + + ) + ) : null} +
+ {data.data_type === EMessageDataType.IMAGE ? ( + chat + ) : ( +

+ {data.text} +

+ )} +
+
+ + ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Chat/PdfSelect.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Chat/PdfSelect.tsx new file mode 100644 index 0000000000..67855b09dd --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Chat/PdfSelect.tsx @@ -0,0 +1,190 @@ +"use client"; + +import { FileTextIcon } from "lucide-react"; +import * as React from "react"; +import { toast } from "sonner"; +import { + apiGetDocumentList, + apiUpdateDocument, + genUUID, + useAppSelector, +} from "@/common"; +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import type { IPdfData, OptionType } from "@/types"; + +export default function PdfSelect() { + const options = useAppSelector((state) => state.global.options); + const { channel, userId } = options; + const [pdfOptions, setPdfOptions] = React.useState([]); + const [selectedPdf, setSelectedPdf] = React.useState(""); + const agentConnected = useAppSelector((state) => state.global.agentConnected); + + React.useEffect(() => { + if (agentConnected) { + getPDFOptions(); + } + }, [agentConnected]); + + const getPDFOptions = async () => { + const res = await apiGetDocumentList(); + setPdfOptions( + res.data.map((item: any) => { + return { + value: item.collection, + label: item.file_name, + }; + }) + ); + setSelectedPdf(""); + }; + + const onUploadSuccess = (data: IPdfData) => { + setPdfOptions([ + ...pdfOptions, + { + value: data.collection, + label: data.fileName, + }, + ]); + setSelectedPdf(data.collection); + }; + + const onSelectPdf = async (val: string) => { + const item = pdfOptions.find((item) => item.value === val); + if (!item) { + // return message.error("Please select a PDF file") + return; + } + setSelectedPdf(val); + await apiUpdateDocument({ + collection: val, + fileName: item.label, + channel, + }); + }; + + return ( + <> + + + + + + + Upload & Select PDF + + +
+ +
+
+
+ + ); +} + +export function UploadPdf({ + onSuccess, +}: { + onSuccess?: (data: IPdfData) => void; +}) { + const agentConnected = useAppSelector((state) => state.global.agentConnected); + const options = useAppSelector((state) => state.global.options); + const { channel, userId } = options; + const [uploading, setUploading] = React.useState(false); + + const handleUpload = async (e: React.ChangeEvent) => { + if (!agentConnected) { + toast.error("Please connect to agent first"); + return; + } + + const file = e.target.files?.[0]; + if (!file) return; + + setUploading(true); + + const formData = new FormData(); + formData.append("file", file); + formData.append("channel_name", channel); + formData.append("uid", String(userId)); + formData.append("request_id", genUUID()); + + try { + const response = await fetch("/api/vector/document/upload", { + method: "POST", + body: formData, + }); + const data = await response.json(); + + if (data.code === "0") { + toast.success(`Upload ${file.name} success`); + const { collection, file_name } = data.data; + onSuccess?.({ + fileName: file_name, + collection, + }); + } else { + toast.info(data.msg); + } + } catch (err) { + toast.error(`Upload ${file.name} failed`); + } finally { + setUploading(false); + } + }; + + return ( +
+ +
+ ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Doodle/DoodlePanel.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Doodle/DoodlePanel.tsx new file mode 100644 index 0000000000..5b6efea302 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Doodle/DoodlePanel.tsx @@ -0,0 +1,144 @@ +"use client"; + +import * as React from "react"; +import { useAppSelector } from "@/common"; +import { Button } from "@/components/ui/button"; +import { cn } from "@/lib/utils"; +import { rtmManager } from "@/manager/rtm"; +import { EMessageDataType, type IChatItem } from "@/types"; + +const STYLES = ["cartoon", "watercolor", "crayon", "pixel art"]; + +export default function DoodlePanel(props: { className?: string }) { + const { className } = props; + const chatItems = useAppSelector((state) => state.global.chatItems); + const options = useAppSelector((state) => state.global.options); + const agentConnected = useAppSelector((state) => state.global.agentConnected); + const rtmConnected = useAppSelector((state) => state.global.rtmConnected); + + const images = React.useMemo( + () => chatItems.filter((i) => i.data_type === EMessageDataType.IMAGE), + [chatItems] + ); + const [selectedIndex, setSelectedIndex] = React.useState( + images.length ? images.length - 1 : -1 + ); + React.useEffect(() => { + if (images.length) { + setSelectedIndex(images.length - 1); + } + }, [images.length]); + + const disableControls = + !options.channel || + !options.userId || + !options.appId || + !options.token || + !rtmConnected || + !agentConnected; + + const current: IChatItem | undefined = + selectedIndex >= 0 ? images[selectedIndex] : undefined; + + const [refine, setRefine] = React.useState(""); + + const handleRefineSubmit = (e: React.FormEvent) => { + e.preventDefault(); + if (!refine || disableControls) return; + rtmManager.sendText(refine); + setRefine(""); + }; + + const handleStyleClick = (style: string) => { + if (disableControls) return; + rtmManager.sendText(`Make the picture ${style} style`); + }; + + return ( +
+
+

Doodle Panel

+
+ {STYLES.map((s) => ( + + ))} +
+
+ +
+ {current ? ( + current doodle + ) : ( +

+ No doodles yet. Describe your idea to start! +

+ )} +
+ +
+ {images.map((img, idx) => ( + + ))} +
+ +
+ setRefine(e.target.value)} + className={cn( + "grow rounded-md border bg-background p-1.5 focus:outline-hidden focus:ring-1 focus:ring-ring", + { + ["cursor-not-allowed"]: disableControls, + } + )} + disabled={disableControls} + /> + +
+
+ ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/AppShell.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/AppShell.tsx new file mode 100644 index 0000000000..7753de22f6 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/AppShell.tsx @@ -0,0 +1,153 @@ +"use client"; + +import * as React from "react"; +import { cn } from "@/lib/utils"; +import { useAppDispatch, useAppSelector } from "@/common"; +import { addChatItem, setOptions, setRoomConnected } from "@/store/reducers/global"; +import DoodleCanvas from "./Canvas"; +import ControlsBar from "./ControlsBar"; +import LoadingAnimator from "./LoadingAnimator"; +import { EMessageDataType, EMessageType, type IChatItem } from "@/types"; + +export default function AppShell() { + const dispatch = useAppDispatch(); + const options = useAppSelector((s) => s.global.options); + const [channel, setChannel] = React.useState(options.channel || "voice_image_kids"); + const [userId, setUserId] = React.useState(options.userId || Math.floor(100000 + Math.random() * 900000)); + const rtcRef = React.useRef(null); + + React.useEffect(() => { + let mounted = true; + import("@/manager/rtc/rtc").then((m) => { + if (mounted) rtcRef.current = m.rtcManager; + }); + return () => { + mounted = false; + }; + }, []); + + const connect = async () => { + const { apiStartService } = await import("@/common"); + await apiStartService({ + channel, + userId, + graphName: "voice_image_kids", + language: "en-US", + voiceType: "female", + }); + const rtc = rtcRef.current; + rtc.on("textChanged", (text: IChatItem) => dispatch(addChatItem(text))); + rtc.on("localTracksChanged", () => {}); + rtc.on("remoteUserChanged", () => {}); + await rtc.createMicrophoneAudioTrack(); + await rtc.join({ channel, userId }); + dispatch( + setOptions({ + ...options, + channel, + userId, + appId: rtc.appId ?? "", + token: rtc.token ?? "", + }) + ); + await rtc.publish(); + dispatch(setRoomConnected(true)); + }; + + const disconnect = async () => { + await rtcRef.current?.destroy(); + dispatch(setRoomConnected(false)); + }; + + return ( +
+
+

+ Doodler +

+
+ setChannel(e.target.value)} + aria-label="Channel" + className={cn( + "rounded-lg border border-[#2b2e35] bg-[#121316] px-3 py-2 text-sm text-white" + )} + /> + setUserId(Number(e.target.value))} + aria-label="User ID" + className={cn( + "rounded-lg border border-[#2b2e35] bg-[#121316] px-3 py-2 text-sm text-white" + )} + /> + + + + Kid Mode + +
+
+
+
+ + +
+ +
+
+ ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/BoardStage.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/BoardStage.tsx new file mode 100644 index 0000000000..8738632a92 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/BoardStage.tsx @@ -0,0 +1,285 @@ +"use client"; + +import * as React from "react"; +import { AnimatePresence, motion } from "framer-motion"; +import { cn } from "@/lib/utils"; +import type { DoodlePhase } from "./MagicCanvasBackground"; + +export type CrayonSwatch = { + id: string; + label: string; + stickerClass: string; + ringClass: string; + penBody: string; + penTop: string; +}; + +export const DEFAULT_CRAYON_SWATCHES: CrayonSwatch[] = [ + { + id: "lavender", + label: "Lavender", + stickerClass: "bg-[#BFA2FF]", + ringClass: "ring-[#5C3DDE]", + penBody: "#5C3DDE", + penTop: "#BFA2FF", + }, + { + id: "mint", + label: "Mint", + stickerClass: "bg-[#9EE7B2]", + ringClass: "ring-[#1C8B43]", + penBody: "#1C8B43", + penTop: "#9EE7B2", + }, + { + id: "sky", + label: "Sky", + stickerClass: "bg-[#9DD8FF]", + ringClass: "ring-[#1D6FE2]", + penBody: "#1D6FE2", + penTop: "#9DD8FF", + }, + { + id: "rose", + label: "Rose", + stickerClass: "bg-[#FFB3C7]", + ringClass: "ring-[#E72D6A]", + penBody: "#E72D6A", + penTop: "#FFB3C7", + }, +]; + +function SurfaceTexture() { + const patternId = React.useId(); + return ( + + + + + + + + + + ); +} + +function Stylus(props: { bodyColor?: string; topColor?: string }) { + const { bodyColor = "#F97316", topColor = "#FB923C" } = props; + return ( + + + + + + + + + + ); +} + +function ToyStylusAnimator(props: { + phase?: DoodlePhase; + reducedMotion: boolean; + bodyColor?: string; + topColor?: string; +}) { + const { phase, reducedMotion, bodyColor, topColor } = props; + + if (reducedMotion) return null; + + const active = Boolean(phase && phase !== "idle"); + const looping = phase === "queued" || phase === "sketch" || phase === "color"; + const anim = React.useMemo(() => { + if (!looping) { + return { + left: "82%", + top: "62%", + rotate: 18, + }; + } + return { + left: ["86%", "44%", "70%", "52%", "78%"], + top: ["56%", "38%", "68%", "54%", "34%"], + rotate: [18, 6, 24, 10, 22], + }; + }, [looping]); + + return ( + + {active ? ( + + + + ) : null} + + ); +} + +export default function BoardStage(props: { + imageUrl?: string; + caption?: string; + className?: string; + overlay?: React.ReactNode; + phase?: DoodlePhase; + reducedMotion?: boolean; + swatches?: CrayonSwatch[]; + activeSwatchId?: string; + onSwatchSelect?: (id: string) => void; + penBodyColor?: string; + penTopColor?: string; +}) { + const { + imageUrl, + caption, + className, + overlay, + phase, + reducedMotion = false, + swatches = DEFAULT_CRAYON_SWATCHES, + activeSwatchId, + onSwatchSelect, + penBodyColor, + penTopColor, + } = props; + const drawingActive = Boolean(phase && phase !== "idle"); + const resolvedActiveId = activeSwatchId ?? swatches[0]?.id; + const activeSwatch = + swatches.find((swatch) => swatch.id === resolvedActiveId) ?? swatches[0]; + const resolvedPenBody = penBodyColor ?? activeSwatch?.penBody ?? "#F97316"; + const resolvedPenTop = penTopColor ?? activeSwatch?.penTop ?? "#FB923C"; + + return ( +
+
+
+
+ {swatches.map((swatch, idx) => { + const isActive = swatch.id === resolvedActiveId; + return ( + + ); + })} +
+ +
+
+ +
+ +
+ + {imageUrl ? ( + +
+ {caption +
+
+ ) : null} +
+
+ +
+ {overlay} + +
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+ ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/Canvas.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/Canvas.tsx new file mode 100644 index 0000000000..edc55051ee --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/Canvas.tsx @@ -0,0 +1,36 @@ +"use client"; + +import * as React from "react"; +import { useAppSelector } from "@/common"; +import { EMessageDataType, type IChatItem } from "@/types"; +import { cn } from "@/lib/utils"; + +export default function DoodleCanvas() { + const chatItems = useAppSelector((s) => s.global.chatItems); + const images = React.useMemo( + () => chatItems.filter((i) => i.data_type === EMessageDataType.IMAGE), + [chatItems] + ); + const current: IChatItem | undefined = images.length + ? images[images.length - 1] + : undefined; + return ( +
+ {current ? ( + doodle + ) : ( +

Describe your idea to start!

+ )} +
+ ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/ControlsBar.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/ControlsBar.tsx new file mode 100644 index 0000000000..8ebe1597ca --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/ControlsBar.tsx @@ -0,0 +1,91 @@ +"use client"; + +import * as React from "react"; +import { useAppSelector } from "@/common"; +import { cn } from "@/lib/utils"; + +const STYLES = ["cartoon", "crayon", "watercolor"]; + +export default function ControlsBar() { + const options = useAppSelector((s) => s.global.options); + const agentConnected = useAppSelector((s) => s.global.agentConnected); + const rtmConnected = useAppSelector((s) => s.global.rtmConnected); + const disable = !options.channel || !options.userId || !rtmConnected || !agentConnected; + const [val, setVal] = React.useState(""); + const rtmRef = React.useRef(null); + + React.useEffect(() => { + let mounted = true; + // Dynamically import to avoid SSR evaluating window-dependent code + import("@/manager/rtm") + .then((m) => { + if (mounted) rtmRef.current = m.rtmManager; + }) + .catch(() => {}); + return () => { + mounted = false; + }; + }, []); + + const submit = (e: React.FormEvent) => { + e.preventDefault(); + if (!val || disable) return; + rtmRef.current?.sendText(val); + setVal(""); + }; + + const styleClick = (s: string) => { + if (disable) return; + rtmRef.current?.sendText(`Make it ${s} style`); + }; + + return ( +
+
+ {STYLES.map((s) => ( + + ))} +
+
+ setVal(e.target.value)} + placeholder="Tell Doodler what to draw" + className={cn( + "grow rounded-xl border border-[#2b2e35] bg-[#15161a] p-3 text-white", + { ["cursor-not-allowed"]: disable } + )} + aria-label="Prompt input" + disabled={disable} + /> + +
+
Sounds can be toggled in Settings.
+
+ ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/FloatingDoodles.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/FloatingDoodles.tsx new file mode 100644 index 0000000000..235bfc4a0e --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/FloatingDoodles.tsx @@ -0,0 +1,697 @@ +"use client"; + +import * as React from "react"; +import { motion } from "framer-motion"; +import { cn } from "@/lib/utils"; + +type DoodleItem = { + key: string; + left: string; + top: string; + size: number; + rotate: number; + opacity: number; + color: string; + variant: + | "star" + | "cloud" + | "spark" + | "swirl" + | "heart" + | "bolt" + | "sun" + | "flower" + | "arrow" + | "gift" + | "moon" + | "leaf"; + duration: number; + delay: number; +}; + +function Star(props: { color: string }) { + const { color } = props; + return ( + + + + ); +} + +function Cloud(props: { color: string }) { + const { color } = props; + return ( + + + + ); +} + +function Spark(props: { color: string }) { + const { color } = props; + return ( + + + + + ); +} + +function Swirl(props: { color: string }) { + const { color } = props; + return ( + + + + ); +} + +function Heart(props: { color: string }) { + const { color } = props; + return ( + + + + ); +} + +function Bolt(props: { color: string }) { + const { color } = props; + return ( + + + + ); +} + +function Sun(props: { color: string }) { + const { color } = props; + return ( + + + + + ); +} + +function Flower(props: { color: string }) { + const { color } = props; + return ( + + + + + + + + + ); +} + +function Arrow(props: { color: string }) { + const { color } = props; + return ( + + + + + ); +} + +function Gift(props: { color: string }) { + const { color } = props; + return ( + + + + + + ); +} + +function Moon(props: { color: string }) { + const { color } = props; + return ( + + + + ); +} + +function Leaf(props: { color: string }) { + const { color } = props; + return ( + + + + + ); +} + +function DoodleSvg(props: { variant: DoodleItem["variant"]; color: string }) { + const { variant, color } = props; + switch (variant) { + case "star": + return ; + case "cloud": + return ; + case "spark": + return ; + case "heart": + return ; + case "bolt": + return ; + case "sun": + return ; + case "flower": + return ; + case "arrow": + return ; + case "gift": + return ; + case "moon": + return ; + case "leaf": + return ; + default: + return ; + } +} + +const INK = "rgba(18, 18, 18, 0.7)"; +const INK_SOFT = "rgba(18, 18, 18, 0.55)"; + +const DEFAULT_DOODLES: DoodleItem[] = [ + { + key: "star-1", + left: "10%", + top: "18%", + size: 64, + rotate: -12, + opacity: 0.32, + color: INK, + variant: "star", + duration: 18, + delay: 0, + }, + { + key: "cloud-1", + left: "22%", + top: "66%", + size: 92, + rotate: 6, + opacity: 0.24, + color: INK_SOFT, + variant: "cloud", + duration: 22, + delay: 1.2, + }, + { + key: "swirl-1", + left: "74%", + top: "24%", + size: 90, + rotate: 10, + opacity: 0.26, + color: INK_SOFT, + variant: "swirl", + duration: 20, + delay: 0.6, + }, + { + key: "spark-1", + left: "86%", + top: "62%", + size: 58, + rotate: 18, + opacity: 0.3, + color: INK, + variant: "spark", + duration: 16, + delay: 1.8, + }, + { + key: "heart-1", + left: "44%", + top: "14%", + size: 54, + rotate: -6, + opacity: 0.24, + color: INK_SOFT, + variant: "heart", + duration: 19, + delay: 0.3, + }, + { + key: "bolt-1", + left: "56%", + top: "78%", + size: 64, + rotate: -18, + opacity: 0.28, + color: INK, + variant: "bolt", + duration: 24, + delay: 2.2, + }, + { + key: "spark-2", + left: "6%", + top: "44%", + size: 52, + rotate: 8, + opacity: 0.26, + color: INK_SOFT, + variant: "spark", + duration: 17, + delay: 0.9, + }, + { + key: "cloud-2", + left: "78%", + top: "6%", + size: 82, + rotate: -8, + opacity: 0.2, + color: INK_SOFT, + variant: "cloud", + duration: 21, + delay: 1.5, + }, + { + key: "star-2", + left: "64%", + top: "44%", + size: 50, + rotate: 16, + opacity: 0.28, + color: INK, + variant: "star", + duration: 14, + delay: 0.4, + }, + { + key: "heart-2", + left: "34%", + top: "78%", + size: 48, + rotate: 12, + opacity: 0.24, + color: INK_SOFT, + variant: "heart", + duration: 18, + delay: 2.4, + }, + { + key: "swirl-2", + left: "30%", + top: "32%", + size: 72, + rotate: -14, + opacity: 0.22, + color: INK_SOFT, + variant: "swirl", + duration: 23, + delay: 1.1, + }, + { + key: "bolt-2", + left: "90%", + top: "38%", + size: 46, + rotate: 22, + opacity: 0.22, + color: INK, + variant: "bolt", + duration: 15, + delay: 2.8, + }, + { + key: "sun-1", + left: "6%", + top: "6%", + size: 72, + rotate: 8, + opacity: 0.26, + color: INK, + variant: "sun", + duration: 20, + delay: 0.7, + }, + { + key: "flower-1", + left: "62%", + top: "8%", + size: 70, + rotate: -6, + opacity: 0.22, + color: INK_SOFT, + variant: "flower", + duration: 22, + delay: 1.9, + }, + { + key: "arrow-1", + left: "18%", + top: "52%", + size: 80, + rotate: 6, + opacity: 0.24, + color: INK, + variant: "arrow", + duration: 19, + delay: 2.6, + }, + { + key: "gift-1", + left: "86%", + top: "20%", + size: 62, + rotate: 12, + opacity: 0.22, + color: INK_SOFT, + variant: "gift", + duration: 18, + delay: 1.3, + }, + { + key: "moon-1", + left: "8%", + top: "80%", + size: 70, + rotate: -8, + opacity: 0.24, + color: INK, + variant: "moon", + duration: 21, + delay: 0.8, + }, + { + key: "leaf-1", + left: "72%", + top: "70%", + size: 76, + rotate: 14, + opacity: 0.2, + color: INK_SOFT, + variant: "leaf", + duration: 24, + delay: 2.2, + }, + { + key: "sun-2", + left: "84%", + top: "78%", + size: 56, + rotate: -6, + opacity: 0.2, + color: INK_SOFT, + variant: "sun", + duration: 18, + delay: 1.6, + }, + { + key: "flower-2", + left: "16%", + top: "30%", + size: 60, + rotate: 10, + opacity: 0.22, + color: INK, + variant: "flower", + duration: 19, + delay: 2.1, + }, + { + key: "arrow-2", + left: "40%", + top: "6%", + size: 78, + rotate: -12, + opacity: 0.24, + color: INK, + variant: "arrow", + duration: 20, + delay: 0.5, + }, + { + key: "gift-2", + left: "6%", + top: "70%", + size: 54, + rotate: 8, + opacity: 0.2, + color: INK_SOFT, + variant: "gift", + duration: 21, + delay: 1.9, + }, + { + key: "moon-2", + left: "46%", + top: "88%", + size: 60, + rotate: 12, + opacity: 0.2, + color: INK_SOFT, + variant: "moon", + duration: 23, + delay: 2.5, + }, + { + key: "leaf-2", + left: "92%", + top: "50%", + size: 62, + rotate: -10, + opacity: 0.18, + color: INK_SOFT, + variant: "leaf", + duration: 19, + delay: 0.9, + }, + { + key: "spark-3", + left: "12%", + top: "54%", + size: 46, + rotate: 18, + opacity: 0.26, + color: INK, + variant: "spark", + duration: 16, + delay: 2.7, + }, + { + key: "star-3", + left: "52%", + top: "38%", + size: 44, + rotate: -8, + opacity: 0.22, + color: INK_SOFT, + variant: "star", + duration: 17, + delay: 1.4, + }, + { + key: "cloud-3", + left: "28%", + top: "10%", + size: 70, + rotate: 6, + opacity: 0.18, + color: INK_SOFT, + variant: "cloud", + duration: 22, + delay: 0.8, + }, + { + key: "bolt-3", + left: "68%", + top: "54%", + size: 52, + rotate: 16, + opacity: 0.24, + color: INK, + variant: "bolt", + duration: 18, + delay: 2.3, + }, + { + key: "heart-3", + left: "22%", + top: "86%", + size: 44, + rotate: -12, + opacity: 0.2, + color: INK_SOFT, + variant: "heart", + duration: 19, + delay: 2.9, + }, + { + key: "swirl-3", + left: "82%", + top: "32%", + size: 68, + rotate: 10, + opacity: 0.2, + color: INK_SOFT, + variant: "swirl", + duration: 24, + delay: 1.7, + }, +]; + +export default function FloatingDoodles(props: { reducedMotion: boolean }) { + const { reducedMotion } = props; + + return ( +
+ {DEFAULT_DOODLES.map((d) => { + const Comp = ( +
+ +
+ ); + + return reducedMotion ? ( +
+ {Comp} +
+ ) : ( + + {Comp} + + ); + })} +
+ ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/ImmersiveShell.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/ImmersiveShell.tsx new file mode 100644 index 0000000000..3b22350cdd --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/ImmersiveShell.tsx @@ -0,0 +1,567 @@ +"use client"; + +import * as React from "react"; +import { motion } from "framer-motion"; +import { toast } from "sonner"; +import { useAppDispatch, useAppSelector, useMultibandTrackVolume } from "@/common"; +import { Button } from "@/components/ui/button"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, +} from "@/components/ui/select"; +import { cn } from "@/lib/utils"; +import { + addChatItem, + setAgentConnected, + setOptions, + setRoomConnected, + setRtmConnected, +} from "@/store/reducers/global"; +import { EMessageDataType, EMessageType, type IChatItem } from "@/types"; +import BoardStage, { DEFAULT_CRAYON_SWATCHES } from "./BoardStage"; +import MagicCanvasBackground, { + type CreativeMode, + type DoodlePhase, +} from "./MagicCanvasBackground"; +import MagicPenAnimator from "./MagicPenAnimator"; +import MouseTrail from "./MouseTrail"; +import TranscriptPanel from "./TranscriptPanel"; +import type { IMicrophoneAudioTrack } from "agora-rtc-sdk-ng"; + +function usePrefersReducedMotion() { + const [reduced, setReduced] = React.useState(false); + React.useEffect(() => { + const mql = window.matchMedia("(prefers-reduced-motion: reduce)"); + setReduced(mql.matches); + const onChange = () => setReduced(mql.matches); + mql.addEventListener("change", onChange); + return () => mql.removeEventListener("change", onChange); + }, []); + return reduced; +} + +function getLatestImage(chatItems: IChatItem[]) { + const images = chatItems.filter((i) => i.data_type === EMessageDataType.IMAGE); + return images.length ? images[images.length - 1] : undefined; +} + +function getLastTime(chatItems: IChatItem[], predicate: (i: IChatItem) => boolean) { + for (let idx = chatItems.length - 1; idx >= 0; idx -= 1) { + const item = chatItems[idx]; + if (predicate(item)) return item.time ?? 0; + } + return 0; +} + +export default function ImmersiveShell() { + const dispatch = useAppDispatch(); + const reducedMotion = usePrefersReducedMotion(); + + const options = useAppSelector((s) => s.global.options); + const roomConnected = useAppSelector((s) => s.global.roomConnected); + const agentConnected = useAppSelector((s) => s.global.agentConnected); + const rtmConnected = useAppSelector((s) => s.global.rtmConnected); + const chatItems = useAppSelector((s) => s.global.chatItems); + + const mode: CreativeMode = "classic"; + + const [channel, setChannel] = React.useState(options.channel || "voice_image_kids"); + const [userId, setUserId] = React.useState( + options.userId || Math.floor(100000 + Math.random() * 900000) + ); + + const rtcRef = React.useRef(null); + const rtmRef = React.useRef(null); + const [connecting, setConnecting] = React.useState(false); + const [micTrack, setMicTrack] = React.useState(); + const [micMediaTrack, setMicMediaTrack] = React.useState(); + const [micMuted, setMicMuted] = React.useState(false); + const [micDevices, setMicDevices] = React.useState< + { label: string; value: string; deviceId: string }[] + >([{ label: "Default microphone", value: "default", deviceId: "" }]); + const [micValue, setMicValue] = React.useState("default"); + const [boardHeight, setBoardHeight] = React.useState(null); + const [crayonId, setCrayonId] = React.useState( + DEFAULT_CRAYON_SWATCHES[0]?.id ?? "crayon" + ); + + React.useEffect(() => { + if (roomConnected) return; + if (options.channel) setChannel(options.channel); + if (options.userId) setUserId(options.userId); + }, [options.channel, options.userId, roomConnected]); + + React.useEffect(() => { + let mounted = true; + import("@/manager/rtc/rtc").then((m) => { + if (mounted) rtcRef.current = m.rtcManager; + }); + import("@/manager/rtm").then((m) => { + if (mounted) rtmRef.current = m.rtmManager; + }); + return () => { + mounted = false; + }; + }, []); + + const onTextChanged = React.useCallback( + (text: IChatItem) => dispatch(addChatItem(text)), + [dispatch] + ); + + const latestImage = React.useMemo(() => getLatestImage(chatItems), [chatItems]); + const lastUserTime = React.useMemo( + () => + getLastTime( + chatItems, + (i) => i.type === EMessageType.USER && i.data_type === EMessageDataType.TEXT + ), + [chatItems] + ); + const lastImageTime = latestImage?.time ?? 0; + const isGenerating = lastUserTime > lastImageTime; + + const [phase, setPhase] = React.useState("idle"); + React.useEffect(() => { + if (isGenerating) { + setPhase("queued"); + const t1 = window.setTimeout(() => setPhase("sketch"), 450); + const t2 = window.setTimeout(() => setPhase("color"), 1550); + return () => { + window.clearTimeout(t1); + window.clearTimeout(t2); + }; + } + + if (lastImageTime > 0 && lastImageTime >= lastUserTime) { + setPhase("complete"); + const t = window.setTimeout(() => setPhase("idle"), 1700); + return () => window.clearTimeout(t); + } + + setPhase("idle"); + return; + }, [isGenerating, lastImageTime, lastUserTime]); + + const canConnect = channel.trim().length > 0 && userId > 0; + const controlsEnabled = roomConnected && agentConnected && rtmConnected; + const isBoardGenerating = + phase === "queued" || phase === "sketch" || phase === "color"; + const isConnected = roomConnected && agentConnected; + + const micBands = useMultibandTrackVolume(micMediaTrack, 10, 80, 520); + const micLevels = React.useMemo(() => { + return micBands.map((band) => { + if (!band.length) return 0; + let sum = 0; + for (let i = 0; i < band.length; i += 1) sum += band[i]; + return sum / band.length; + }); + }, [micBands]); + + React.useEffect(() => { + if (!micTrack) { + setMicMuted(false); + return; + } + micTrack.setMuted(micMuted); + }, [micMuted, micTrack]); + + React.useEffect(() => { + if (!micTrack) { + setMicDevices([{ label: "Default microphone", value: "default", deviceId: "" }]); + setMicValue("default"); + return; + } + let active = true; + const currentLabel = micTrack.getTrackLabel() || "Default microphone"; + const load = async () => { + try { + const mod = await import("agora-rtc-sdk-ng"); + if (!active) return; + const arr = await mod.default.getMicrophones(); + if (!active) return; + const usedValues = new Set(["default"]); + const items = arr.map((item, index) => { + const label = item.label?.trim() || `Microphone ${index + 1}`; + let value = (item.deviceId || label).trim(); + if (!value) value = `mic-${index + 1}`; + if (usedValues.has(value)) { + value = `${value}-${index + 1}`; + } + usedValues.add(value); + return { + label, + value, + deviceId: item.deviceId, + }; + }); + setMicDevices([ + { label: "Default microphone", value: "default", deviceId: "" }, + ...items, + ]); + const found = items.find((item) => item.label === currentLabel); + setMicValue(found?.value ?? "default"); + } catch { + if (!active) return; + setMicDevices([{ label: "Default microphone", value: "default", deviceId: "" }]); + setMicValue("default"); + } + }; + load(); + return () => { + active = false; + }; + }, [micTrack]); + + const connect = async () => { + if (!canConnect) { + toast.error("Please enter a channel and user id."); + return; + } + + if (connecting) return; + setConnecting(true); + + try { + const { apiStartService } = await import("@/common"); + const startResp = await apiStartService({ + channel, + userId, + graphName: "voice_image_kids", + language: "en-US", + voiceType: "female", + }); + const { code, msg } = startResp || {}; + if (code != null && String(code) !== "0") { + throw new Error(msg || `Agent start failed (code=${code})`); + } + dispatch(setAgentConnected(true)); + + const rtc = rtcRef.current; + if (!rtc) { + throw new Error("RTC manager not ready yet. Please try again."); + } + rtc.off("textChanged", onTextChanged); + rtc.on("textChanged", onTextChanged); + await rtc.createMicrophoneAudioTrack(); + const track: IMicrophoneAudioTrack | undefined = rtc.localTracks?.audioTrack; + setMicTrack(track); + setMicMediaTrack(track?.getMediaStreamTrack()); + await rtc.join({ channel, userId }); + + dispatch( + setOptions({ + ...options, + channel, + userId, + appId: rtc.appId ?? "", + token: rtc.token ?? "", + }) + ); + await rtc.publish(); + dispatch(setRoomConnected(true)); + + const rtm = rtmRef.current; + if (rtm?.init) { + await rtm.init({ + channel, + userId, + appId: rtc.appId ?? "", + token: rtc.token ?? "", + }); + const ok = Boolean(rtm?._client); + dispatch(setRtmConnected(ok)); + if (!ok) { + toast.error("Connected, but messaging failed. Text prompts are disabled."); + } + } + + toast.success("Doodle board connected."); + } catch (err: any) { + console.error(err); + try { + const { apiStopService } = await import("@/common"); + await apiStopService(channel); + } catch { + // best-effort + } + toast.error(err?.message || "Failed to connect."); + dispatch(setAgentConnected(false)); + dispatch(setRoomConnected(false)); + dispatch(setRtmConnected(false)); + } finally { + setConnecting(false); + } + }; + + const disconnect = async () => { + if (connecting) return; + setConnecting(true); + try { + const { apiStopService } = await import("@/common"); + await apiStopService(channel); + } catch { + // best-effort + } + try { + await rtmRef.current?.destroy?.(); + rtcRef.current?.off?.("textChanged", onTextChanged); + await rtcRef.current?.destroy?.(); + } finally { + dispatch(setRtmConnected(false)); + dispatch(setRoomConnected(false)); + dispatch(setAgentConnected(false)); + setMicMediaTrack(undefined); + setMicTrack(undefined); + toast.message("Disconnected."); + setConnecting(false); + } + }; + + const sendText = async (text: string) => { + const msg = text.trim(); + if (!msg) return; + if (!controlsEnabled) { + toast.error("Connect the board first."); + return; + } + try { + await rtmRef.current?.sendText?.(msg); + dispatch( + addChatItem({ + userId: options.userId || userId, + text: msg, + type: EMessageType.USER, + data_type: EMessageDataType.TEXT, + isFinal: true, + time: Date.now(), + }) + ); + } catch (err: any) { + console.error(err); + toast.error(err?.message || "Failed to send."); + } + }; + + const onMicChange = async (value: string) => { + setMicValue(value); + const target = micDevices.find((item) => item.value === value); + if (!target || !micTrack) return; + await micTrack.setDevice(target.deviceId); + }; + + const selectedMicLabel = + micDevices.find((item) => item.value === micValue)?.label || + "Microphone"; + + const boardRef = React.useRef(null); + React.useEffect(() => { + if (!boardRef.current) return; + const node = boardRef.current; + let raf = 0; + const update = () => { + raf = window.requestAnimationFrame(() => { + const next = Math.round(node.getBoundingClientRect().height); + setBoardHeight((prev) => (prev === next ? prev : next)); + }); + }; + update(); + const observer = new ResizeObserver(update); + observer.observe(node); + return () => { + observer.disconnect(); + if (raf) window.cancelAnimationFrame(raf); + }; + }, []); + + const boardPose = React.useMemo(() => { + if (reducedMotion) { + return { x: 0, rotateX: 0, rotateY: 0, scale: 1 }; + } + if (isBoardGenerating) { + return { x: -32, rotateX: 7, rotateY: -14, scale: 1.02 }; + } + return { x: 0, rotateX: 0, rotateY: 0, scale: 1 }; + }, [isBoardGenerating, reducedMotion]); + + const boardPoseTransition = React.useMemo(() => { + if (reducedMotion) return { duration: 0 }; + return { + type: "spring", + stiffness: isBoardGenerating ? 200 : 260, + damping: isBoardGenerating ? 24 : 26, + mass: 0.7, + }; + }, [isBoardGenerating, reducedMotion]); + + const activeCrayon = React.useMemo( + () => + DEFAULT_CRAYON_SWATCHES.find((swatch) => swatch.id === crayonId) ?? + DEFAULT_CRAYON_SWATCHES[0], + [crayonId] + ); + + const penBodyColor = activeCrayon?.penBody; + const penTopColor = activeCrayon?.penTop; + + return ( +
+ + + +
+
+
+ + + + } + /> + + + +
+
+ +
+
+
+ + + + + +
+
+
+
+
+ ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/LoadingAnimator.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/LoadingAnimator.tsx new file mode 100644 index 0000000000..41a6a07e51 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/LoadingAnimator.tsx @@ -0,0 +1,40 @@ +"use client"; + +import * as React from "react"; +import { useAppSelector } from "@/common"; +import { cn } from "@/lib/utils"; +import { EMessageDataType, EMessageType } from "@/types"; + +export default function LoadingAnimator() { + const items = useAppSelector((s) => s.global.chatItems); + const lastImageTime = React.useMemo(() => { + const img = [...items].reverse().find((i) => i.data_type === EMessageDataType.IMAGE); + return img?.time ?? 0; + }, [items]); + const lastUserTime = React.useMemo(() => { + const usr = [...items] + .reverse() + .find( + (i) => i.type === EMessageType.USER && i.data_type === EMessageDataType.TEXT + ); + return usr?.time ?? 0; + }, [items]); + const active = lastUserTime > lastImageTime; + return ( +
+
+
+
+
+ Doodling... +
+
+
+ ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/MagicCanvasBackground.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/MagicCanvasBackground.tsx new file mode 100644 index 0000000000..00620badc6 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/MagicCanvasBackground.tsx @@ -0,0 +1,74 @@ +"use client"; + +import * as React from "react"; +import { motion } from "framer-motion"; +import { cn } from "@/lib/utils"; + +export type DoodlePhase = "idle" | "queued" | "sketch" | "color" | "complete"; +export type CreativeMode = "classic" | "neon"; + +export default function MagicCanvasBackground(props: { + phase: DoodlePhase; + mode: CreativeMode; + reducedMotion?: boolean; +}) { + const { phase, mode, reducedMotion = false } = props; + const isGenerating = phase === "queued" || phase === "sketch" || phase === "color"; + const showDream = phase === "complete"; + const tileStart = "0px 0px"; + const tileEnd = "160px 140px"; + + return ( +
+ + + + +
+
+ ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/MagicPenAnimator.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/MagicPenAnimator.tsx new file mode 100644 index 0000000000..934f470870 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/MagicPenAnimator.tsx @@ -0,0 +1,239 @@ +"use client"; + +import * as React from "react"; +import { AnimatePresence, motion } from "framer-motion"; +import { cn } from "@/lib/utils"; +import type { CreativeMode, DoodlePhase } from "./MagicCanvasBackground"; + +function PenIcon(props: { + mode: CreativeMode; + bodyColor?: string; + topColor?: string; +}) { + const { mode, bodyColor, topColor } = props; + const isNeon = mode === "neon"; + const body = bodyColor ?? (isNeon ? "#FF8A3D" : "#F97316"); + const bodyTop = topColor ?? (isNeon ? "#FFB457" : "#FB923C"); + const stripe = isNeon ? "#0B1220" : "#1F1F1F"; + const outline = isNeon ? "rgba(124,255,250,0.4)" : "rgba(0,0,0,0.18)"; + return ( + + + + + + + + + + + + ); +} + +function scribbleStroke(mode: CreativeMode, phase: DoodlePhase) { + const isNeon = mode === "neon"; + if (phase === "sketch") { + return { + color: isNeon ? "hsla(180, 95%, 60%, 0.75)" : "rgba(44, 33, 22, 0.45)", + width: isNeon ? 3.5 : 3, + dash: isNeon ? "10 10" : "9 10", + glow: isNeon, + }; + } + if (phase === "color") { + return { + color: isNeon ? "hsla(280, 95%, 68%, 0.75)" : "rgba(249, 115, 22, 0.35)", + width: isNeon ? 4 : 3.4, + dash: isNeon ? "0" : "0", + glow: isNeon, + }; + } + return { + color: isNeon ? "hsla(200, 95%, 60%, 0.7)" : "rgba(44, 33, 22, 0.35)", + width: isNeon ? 3.2 : 3, + dash: "10 10", + glow: isNeon, + }; +} + +export default function MagicPenAnimator(props: { + phase: DoodlePhase; + mode: CreativeMode; + reducedMotion: boolean; + showPen?: boolean; + penBodyColor?: string; + penTopColor?: string; +}) { + const { phase, mode, reducedMotion, showPen = true, penBodyColor, penTopColor } = + props; + const show = phase !== "idle"; + const isNeon = mode === "neon"; + + const penAnimation = React.useMemo(() => { + if (phase === "queued") { + return { + x: ["-12%", "18%", "18%"], + y: ["-10%", "22%", "24%"], + rotate: [-10, 6, -3], + }; + } + if (phase === "sketch") { + return { + x: ["18%", "64%", "42%", "76%", "30%", "58%"], + y: ["24%", "30%", "64%", "58%", "46%", "34%"], + rotate: [8, 22, -18, 12, -10, 18], + }; + } + if (phase === "color") { + return { + x: ["58%", "38%", "70%", "52%"], + y: ["34%", "56%", "50%", "36%"], + rotate: [10, -6, 14, 6], + }; + } + return { + x: ["52%", "66%", "110%"], + y: ["52%", "20%", "-30%"], + rotate: [8, 28, 48], + }; + }, [phase]); + + const penTransition = React.useMemo(() => { + if (phase === "queued") { + return { duration: 0.9, ease: [0.22, 1, 0.36, 1] }; + } + if (phase === "sketch") { + return { duration: 1.8, ease: "easeInOut", repeat: Infinity }; + } + if (phase === "color") { + return { duration: 2.4, ease: "easeInOut", repeat: Infinity }; + } + return { duration: 0.9, ease: [0.22, 1, 0.36, 1] }; + }, [phase]); + + const stroke = scribbleStroke(mode, phase); + + if (reducedMotion) return null; + + return ( + + {show ? ( + + + {phase !== "complete" ? ( + <> + + + + ) : ( + <> + + {Array.from({ length: 12 }).map((_, i) => ( + + ))} + + )} + + + {showPen ? ( + + + + ) : null} + + ) : null} + + ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/MouseTrail.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/MouseTrail.tsx new file mode 100644 index 0000000000..133a7bd3a8 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/MouseTrail.tsx @@ -0,0 +1,152 @@ +"use client"; + +import * as React from "react"; + +type CreativeMode = "classic" | "neon"; + +type Particle = { + x: number; + y: number; + vx: number; + vy: number; + r: number; + life: number; + ttl: number; + hue: number; +}; + +export default function MouseTrail(props: { + enabled: boolean; + mode: CreativeMode; +}) { + const { enabled, mode } = props; + const canvasRef = React.useRef(null); + const particlesRef = React.useRef([]); + const rafRef = React.useRef(null); + const pointerRef = React.useRef<{ x: number; y: number; t: number } | null>( + null + ); + + React.useEffect(() => { + if (!enabled) { + particlesRef.current = []; + return; + } + const canvas = canvasRef.current; + if (!canvas) return; + const ctx = canvas.getContext("2d"); + if (!ctx) return; + + const dpr = () => Math.max(1, Math.min(2, window.devicePixelRatio || 1)); + + const resize = () => { + const ratio = dpr(); + canvas.width = Math.floor(window.innerWidth * ratio); + canvas.height = Math.floor(window.innerHeight * ratio); + canvas.style.width = `${window.innerWidth}px`; + canvas.style.height = `${window.innerHeight}px`; + ctx.setTransform(ratio, 0, 0, ratio, 0, 0); + }; + + resize(); + window.addEventListener("resize", resize); + + const spawn = (x: number, y: number, speedX: number, speedY: number) => { + const ttl = mode === "neon" ? 520 : 340; + const r = mode === "neon" ? 2.2 : 1.6; + const hue = mode === "neon" ? 175 + Math.random() * 90 : 32; + particlesRef.current.push({ + x, + y, + vx: speedX, + vy: speedY, + r: r + Math.random() * 1.2, + life: 0, + ttl, + hue, + }); + if (particlesRef.current.length > 180) { + particlesRef.current.splice(0, particlesRef.current.length - 180); + } + }; + + const onMove = (e: PointerEvent) => { + const now = performance.now(); + const last = pointerRef.current; + pointerRef.current = { x: e.clientX, y: e.clientY, t: now }; + if (!last) return; + const dt = Math.max(8, now - last.t); + const dx = e.clientX - last.x; + const dy = e.clientY - last.y; + const vx = dx / dt; + const vy = dy / dt; + const dist = Math.hypot(dx, dy); + const count = Math.min(6, Math.max(1, Math.floor(dist / 18))); + for (let i = 0; i < count; i += 1) { + const t = (i + 1) / (count + 1); + spawn(last.x + dx * t, last.y + dy * t, vx * 10, vy * 10); + } + }; + + window.addEventListener("pointermove", onMove, { passive: true }); + + const tick = (now: number) => { + ctx.clearRect(0, 0, canvas.width, canvas.height); + + const particles = particlesRef.current; + ctx.save(); + ctx.globalCompositeOperation = mode === "neon" ? "lighter" : "source-over"; + + for (let i = particles.length - 1; i >= 0; i -= 1) { + const p = particles[i]; + p.life += 16; + const a = Math.max(0, 1 - p.life / p.ttl); + p.x += p.vx * 0.016; + p.y += p.vy * 0.016; + p.vx *= 0.92; + p.vy *= 0.92; + + if (a <= 0.02) { + particles.splice(i, 1); + continue; + } + + if (mode === "neon") { + ctx.shadowBlur = 14 * a; + ctx.shadowColor = `hsla(${p.hue}, 95%, 62%, ${0.65 * a})`; + ctx.fillStyle = `hsla(${p.hue}, 95%, 62%, ${0.55 * a})`; + } else { + ctx.shadowBlur = 0; + ctx.fillStyle = `rgba(54, 42, 28, ${0.18 * a})`; + } + + ctx.beginPath(); + ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2); + ctx.fill(); + } + + ctx.restore(); + rafRef.current = window.requestAnimationFrame(tick); + }; + + rafRef.current = window.requestAnimationFrame(tick); + + return () => { + window.removeEventListener("resize", resize); + window.removeEventListener("pointermove", onMove); + if (rafRef.current) window.cancelAnimationFrame(rafRef.current); + rafRef.current = null; + particlesRef.current = []; + pointerRef.current = null; + }; + }, [enabled, mode]); + + return ( + + ); +} + diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/TranscriptPanel.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/TranscriptPanel.tsx new file mode 100644 index 0000000000..7a342c5b41 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Doodler/TranscriptPanel.tsx @@ -0,0 +1,127 @@ +"use client"; + +import * as React from "react"; +import { useAppSelector, useAutoScroll } from "@/common"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { cn } from "@/lib/utils"; +import { EMessageDataType, EMessageType, type IChatItem } from "@/types"; + +function getTranscriptItems(items: IChatItem[]) { + return items.filter( + (i) => + i.data_type === EMessageDataType.TEXT && + typeof i.text === "string" && + i.text.trim().length > 0 + ); +} + +export default function TranscriptPanel(props: { + className?: string; + disabled?: boolean; + onSend?: (text: string) => Promise | void; + placeholder?: string; + style?: React.CSSProperties; +}) { + const { className, disabled = false, onSend, placeholder, style } = props; + const items = useAppSelector((s) => s.global.chatItems); + const transcript = React.useMemo(() => getTranscriptItems(items), [items]); + const containerRef = React.useRef(null); + const [value, setValue] = React.useState(""); + + useAutoScroll(containerRef); + + const canSend = !disabled && Boolean(onSend) && value.trim().length > 0; + + const onSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + if (!canSend || !onSend) return; + await onSend(value); + setValue(""); + }; + + return ( +
+
+
+ +

Transcript

+
+ + {transcript.length ? `${transcript.length}` : "—"} + +
+ +
+ {transcript.length ? ( +
+ {transcript.map((item, idx) => { + const isUser = item.type === EMessageType.USER; + return ( +
+
+
+ {isUser ? "You" : "Agent"} + {item.isFinal === false ? : null} +
+
+ {item.text} +
+
+
+ ); + })} +
+ ) : ( +

+ Your transcript will show up here. +

+ )} +
+ + {onSend ? ( +
+
+ setValue(e.target.value)} + placeholder={placeholder ?? "Type a prompt…"} + className="h-11 bg-white/80 crayon-control" + disabled={disabled} + /> + +
+
+ ) : null} +
+ ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Dynamic/NetworkIndicator.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Dynamic/NetworkIndicator.tsx new file mode 100644 index 0000000000..a0e65a61af --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Dynamic/NetworkIndicator.tsx @@ -0,0 +1,29 @@ +"use client"; + +import type { NetworkQuality } from "agora-rtc-sdk-ng"; +import * as React from "react"; +import { NetworkIconByLevel } from "@/components/Icon"; +import { rtcManager } from "@/manager"; + +export default function NetworkIndicator() { + const [networkQuality, setNetworkQuality] = React.useState(); + + React.useEffect(() => { + rtcManager.on("networkQuality", onNetworkQuality); + + return () => { + rtcManager.off("networkQuality", onNetworkQuality); + }; + }, []); + + const onNetworkQuality = (quality: NetworkQuality) => { + setNetworkQuality(quality); + }; + + return ( + + ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Dynamic/RTCCard.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Dynamic/RTCCard.tsx new file mode 100644 index 0000000000..b425798355 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Dynamic/RTCCard.tsx @@ -0,0 +1,181 @@ +"use client"; + +import type { + ICameraVideoTrack, + ILocalVideoTrack, + IMicrophoneAudioTrack, +} from "agora-rtc-sdk-ng"; +import dynamic from "next/dynamic"; +import * as React from "react"; +import { + useAppDispatch, + useAppSelector, + useIsCompactLayout, + VideoSourceType, + VOICE_OPTIONS, +} from "@/common"; +import Avatar from "@/components/Agent/AvatarTrulience"; +import VideoBlock from "@/components/Agent/Camera"; +import MicrophoneBlock from "@/components/Agent/Microphone"; +import AgentView from "@/components/Agent/View"; +import AgentVoicePresetSelect from "@/components/Agent/VoicePresetSelect"; +import ChatCard from "@/components/Chat/ChatCard"; +import { cn } from "@/lib/utils"; +import { type IRtcUser, type IUserTracks, rtcManager } from "@/manager"; +import { + addChatItem, + setOptions, + setRoomConnected, + setVoiceType, +} from "@/store/reducers/global"; +import { EMessageType, type IChatItem, ITextItem } from "@/types"; + +let hasInit: boolean = false; + +export default function RTCCard(props: { className?: string }) { + const { className } = props; + + const dispatch = useAppDispatch(); + const options = useAppSelector((state) => state.global.options); + const trulienceSettings = useAppSelector( + (state) => state.global.trulienceSettings + ); + const { userId, channel } = options; + const [videoTrack, setVideoTrack] = React.useState(); + const [audioTrack, setAudioTrack] = React.useState(); + const [screenTrack, setScreenTrack] = React.useState(); + const [remoteuser, setRemoteUser] = React.useState(); + const [videoSourceType, setVideoSourceType] = React.useState( + VideoSourceType.CAMERA + ); + const useTrulienceAvatar = trulienceSettings.enabled; + const avatarInLargeWindow = trulienceSettings.avatarDesktopLargeWindow; + + const isCompactLayout = useIsCompactLayout(); + + const DynamicChatCard = dynamic(() => import("@/components/Chat/ChatCard"), { + ssr: false, + }); + + React.useEffect(() => { + if (!options.channel) { + return; + } + if (hasInit) { + return; + } + + init(); + + return () => { + if (hasInit) { + destory(); + } + }; + }, [options.channel]); + + const init = async () => { + console.log("[rtc] init"); + rtcManager.on("localTracksChanged", onLocalTracksChanged); + rtcManager.on("textChanged", onTextChanged); + rtcManager.on("remoteUserChanged", onRemoteUserChanged); + await rtcManager.createCameraTracks(); + await rtcManager.createMicrophoneAudioTrack(); + await rtcManager.join({ + channel, + userId, + }); + dispatch( + setOptions({ + ...options, + appId: rtcManager.appId ?? "", + token: rtcManager.token ?? "", + }) + ); + await rtcManager.publish(); + dispatch(setRoomConnected(true)); + hasInit = true; + }; + + const destory = async () => { + console.log("[rtc] destory"); + rtcManager.off("textChanged", onTextChanged); + rtcManager.off("localTracksChanged", onLocalTracksChanged); + rtcManager.off("remoteUserChanged", onRemoteUserChanged); + await rtcManager.destroy(); + dispatch(setRoomConnected(false)); + hasInit = false; + }; + + const onRemoteUserChanged = (user: IRtcUser) => { + console.log("[rtc] onRemoteUserChanged", user); + if (useTrulienceAvatar) { + // trulience SDK will play audio in synch with mouth + user.audioTrack?.stop(); + } + if (user.audioTrack || user.videoTrack) { + setRemoteUser(user); + } else { + setRemoteUser(undefined); + } + }; + + const onLocalTracksChanged = (tracks: IUserTracks) => { + console.log("[rtc] onLocalTracksChanged", tracks); + const { videoTrack, audioTrack, screenTrack } = tracks; + setVideoTrack(videoTrack); + setScreenTrack(screenTrack); + if (audioTrack) { + setAudioTrack(audioTrack); + } + }; + + const onTextChanged = (text: IChatItem) => { + console.log("[rtc] onTextChanged", text); + dispatch(addChatItem(text)); + }; + + const onVoiceChange = (value: any) => { + dispatch(setVoiceType(value)); + }; + + const onVideoSourceTypeChange = async (value: VideoSourceType) => { + await rtcManager.switchVideoSource(value); + setVideoSourceType(value); + }; + + return ( +
+ {/* Top region (Avatar or ChatCard) */} +
+ {useTrulienceAvatar ? ( + !avatarInLargeWindow ? ( +
+ +
+ ) : ( + !isCompactLayout && ( + + ) + ) + ) : ( + + )} +
+ + {/* Bottom region for microphone and video blocks - always visible */} +
+ + +
+
+ ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Icon/index.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Icon/index.tsx new file mode 100644 index 0000000000..b08ccee899 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Icon/index.tsx @@ -0,0 +1,532 @@ +import type * as React from "react"; + +import { cn } from "@/lib/utils"; + +export const GitHubIcon = (props: React.SVGProps) => { + return ( + + + + ); +}; + +export const AnimatedSpinnerIcon = (props: React.SVGProps) => { + const { className, ...rest } = props; + return ( + + + + + ); +}; + +export const LogoIcon = (props: React.SVGProps) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export const SmallLogoIcon = (props: React.SVGProps) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export const InfoIcon = (props: React.SVGProps) => { + return ( + + + + ); +}; + +export const PaletteIcon = (props: React.SVGProps) => { + return ( + + + + + + + + ); +}; + +export const NetworkAverageIcon = (props: React.SVGProps) => { + return ( + + + + + + + ); +}; + +export const NetworkDisconnectedIcon = ( + props: React.SVGProps +) => { + return ( + + + + + ); +}; + +export const NetworkExcellentIcon = (props: React.SVGProps) => { + return ( + + + + ); +}; + +export const NetworkGoodIcon = (props: React.SVGProps) => { + return ( + + + + + + + ); +}; + +export const NetworkPoorIcon = (props: React.SVGProps) => { + return ( + + + + + + + ); +}; + +export const NetworkIconByLevel = ( + props: React.SVGProps & { level?: number } +) => { + const { level, ...rest } = props; + switch (level) { + case 0: + return ; + case 1: + return ; + case 2: + return ; + case 3: + case 4: + return ; + case 5: + return ; + case 6: + default: + return ; + } +}; + +export const VoiceIcon = (props: React.SVGProps) => { + return ( + + + + ); +}; + +export const MicMuteIcon = (props: React.SVGProps) => { + return ( + + + + ); +}; + +export const MicActiveIcon = (props: React.SVGProps) => { + return ( + + + + ); +}; + +export const MicIconByStatus = ( + props: React.SVGProps & { active?: boolean; color?: string } +) => { + const { active, color, ...rest } = props; + if (active) { + return ; + } + return ; +}; + +export const CameraDisabledIcon = (props: React.SVGProps) => { + return ( + + + + ); +}; + +export const CameraActiveIcon = (props: React.SVGProps) => { + return ( + + + + ); +}; + +export const CamIconByStatus = ( + props: React.SVGProps & { active?: boolean; color?: string } +) => { + const { active, color, ...rest } = props; + if (active) { + return ; + } + return ; +}; diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Layout/Action.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Layout/Action.tsx new file mode 100644 index 0000000000..3c3322611b --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Layout/Action.tsx @@ -0,0 +1,187 @@ +"use client"; + +import * as React from "react"; +import { toast } from "sonner"; +import { + apiPing, + apiStartService, + apiStopService, + EMobileActiveTab, + isEditModeOn, + MOBILE_ACTIVE_TAB_MAP, + useAppDispatch, + useAppSelector, +} from "@/common"; +import { LoadingButton } from "@/components/Button/LoadingButton"; +import { RemoteGraphSelect } from "@/components/Chat/ChatCfgGraphSelect"; +import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { cn } from "@/lib/utils"; +import { setAgentConnected, setMobileActiveTab } from "@/store/reducers/global"; +import { TrulienceCfgSheet } from "../Chat/ChatCfgTrulienceSetting"; + +let intervalId: NodeJS.Timeout | null = null; + +export default function Action(props: { className?: string }) { + const { className } = props; + const dispatch = useAppDispatch(); + const agentConnected = useAppSelector((state) => state.global.agentConnected); + const channel = useAppSelector((state) => state.global.options.channel); + const userId = useAppSelector((state) => state.global.options.userId); + const language = useAppSelector((state) => state.global.language); + const voiceType = useAppSelector((state) => state.global.voiceType); + const selectedGraphId = useAppSelector( + (state) => state.global.selectedGraphId + ); + const graphList = useAppSelector((state) => state.global.graphList); + const mobileActiveTab = useAppSelector( + (state) => state.global.mobileActiveTab + ); + const [loading, setLoading] = React.useState(false); + + React.useEffect(() => { + if (channel) { + checkAgentConnected(); + } + }, [channel]); + + const checkAgentConnected = async () => { + const res: any = await apiPing(channel); + if (res?.code == 0) { + dispatch(setAgentConnected(true)); + } + }; + + const onClickConnect = async () => { + if (loading) { + return; + } + setLoading(true); + if (agentConnected) { + await apiStopService(channel); + dispatch(setAgentConnected(false)); + toast.success("Agent disconnected"); + stopPing(); + } else { + const selectedGraph = graphList.find( + (graph) => graph.graph_id === selectedGraphId + ); + if (!selectedGraph) { + toast.error("Please select a graph first"); + setLoading(false); + return; + } + + const res = await apiStartService({ + channel, + userId, + graphName: selectedGraph.name, + language, + voiceType, + }); + const { code, msg } = res || {}; + if (code != 0) { + if (code == "10001") { + toast.error( + "The number of users experiencing the program simultaneously has exceeded the limit. Please try again later." + ); + } else { + toast.error(`code:${code},msg:${msg}`); + } + setLoading(false); + throw new Error(msg); + } + dispatch(setAgentConnected(true)); + toast.success("Agent connected"); + startPing(); + } + setLoading(false); + }; + + const startPing = () => { + if (intervalId) { + stopPing(); + } + intervalId = setInterval(() => { + apiPing(channel); + }, 3000); + }; + + const stopPing = () => { + if (intervalId) { + clearInterval(intervalId); + intervalId = null; + } + }; + + const onChangeMobileActiveTab = (tab: string) => { + dispatch(setMobileActiveTab(tab as EMobileActiveTab)); + }; + + return ( + <> + {/* Action Bar */} +
+ {/* -- Description Part */} +
+ Description + + A Realtime Conversational AI Agent powered by TEN + +
+ +
+ {/* -- Tabs Section */} + + + {Object.values(EMobileActiveTab).map((tab) => ( + + {MOBILE_ACTIVE_TAB_MAP[tab]} + + ))} + + + + {/* -- Graph Select Part */} +
+ + {isEditModeOn && ( + <> + + {/* */} + {/* */} + + )} + + {/* -- Action Button */} +
+ + {loading + ? "Connecting" + : !agentConnected + ? "Connect" + : "Disconnect"} + +
+
+
+
+ + ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Layout/Header.module.css b/ai_agents/agents/examples/doodler/frontend/src/components/Layout/Header.module.css new file mode 100644 index 0000000000..170ce2631c --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Layout/Header.module.css @@ -0,0 +1,18 @@ +.colorPicker :global(.react-colorful) { + width: 220px; + height: 8px; +} + +.colorPicker :global(.react-colorful__saturation) { + display: none; +} + +.colorPicker :global(.react-colorful__hue) { + border-radius: 8px !important; + height: 8px; +} + +.colorPicker :global(.react-colorful__pointer) { + width: 24px; + height: 24px; +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Layout/Header.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Layout/Header.tsx new file mode 100644 index 0000000000..45262cea96 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Layout/Header.tsx @@ -0,0 +1,26 @@ +import { LogoIcon, SmallLogoIcon } from "@/components/Icon"; +import { cn } from "@/lib/utils"; +import { HeaderActions, HeaderRoomInfo } from "./HeaderComponents"; + +export default function Header(props: { className?: string }) { + const { className } = props; + return ( + <> + {/* Header */} +
+
+ {/* + */} +

TEN Agent

+
+ + +
+ + ); +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/Layout/HeaderComponents.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/Layout/HeaderComponents.tsx new file mode 100644 index 0000000000..c8c1b7ac76 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/Layout/HeaderComponents.tsx @@ -0,0 +1,203 @@ +"use client"; + +import dynamic from "next/dynamic"; +import NextLink from "next/link"; +import * as React from "react"; +import { HexColorPicker } from "react-colorful"; +import { + COLOR_LIST, + GITHUB_URL, + useAppDispatch, + useAppSelector, +} from "@/common"; +import { GitHubIcon, InfoIcon, PaletteIcon } from "@/components/Icon"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip"; +import { cn } from "@/lib/utils"; +import { setThemeColor } from "@/store/reducers/global"; + +import styles from "./Header.module.css"; + +export function HeaderRoomInfo() { + const options = useAppSelector((state) => state.global.options); + const { channel, userId } = options; + + const roomConnected = useAppSelector((state) => state.global.roomConnected); + const agentConnected = useAppSelector((state) => state.global.agentConnected); + + const roomConnectedText = React.useMemo(() => { + return roomConnected ? "TRUE" : "FALSE"; + }, [roomConnected]); + + const agentConnectedText = React.useMemo(() => { + return agentConnected ? "TRUE" : "FALSE"; + }, [agentConnected]); + + return ( + <> + + + + + + Channel Name:{" "} + + {channel} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
INFO
Room:{channel}
Participant:{userId}
+
+
+ STATUS +
Room connected:{roomConnectedText}
Agent connected:{agentConnectedText}
+
+
+
+ + ); +} + +export function HeaderActions() { + return ( +
+ + + GitHub + + + +
+ ); +} + +export const ThemePalettePopover = () => { + const themeColor = useAppSelector((state) => state.global.themeColor); + const dispatch = useAppDispatch(); + + const onMainClickSelect = (index: number) => { + const target = COLOR_LIST[index]; + if (target.active !== themeColor) { + dispatch(setThemeColor(target.active)); + } + }; + + const onColorSliderChange = (color: string) => { + console.log(color); + dispatch(setThemeColor(color)); + }; + + return ( + <> + + + + + +
+ STYLE +
+
+ {COLOR_LIST.map((item, index) => { + const isSelected = item.active === themeColor; + return ( + + ); + })} +
+
+ +
+
+
+ + ); +}; + +// export const Network = () => { +// const [networkQuality, setNetworkQuality] = React.useState() + +// React.useEffect(() => { +// rtcManager.on("networkQuality", onNetworkQuality) + +// return () => { +// rtcManager.off("networkQuality", onNetworkQuality) +// } +// }, []) + +// const onNetworkQuality = (quality: NetworkQuality) => { +// setNetworkQuality(quality) +// } + +// return ( +// +// ) +// } + +const NetworkIndicator = dynamic( + () => import("@/components/Dynamic/NetworkIndicator"), + { + ssr: false, + } +); diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/authInitializer/index.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/authInitializer/index.tsx new file mode 100644 index 0000000000..8d0d924c90 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/authInitializer/index.tsx @@ -0,0 +1,87 @@ +"use client"; + +import { type ReactNode, useEffect, useRef } from "react"; +import { + getOptionsFromLocal, + getRandomChannel, + getRandomUserId, + getTrulienceSettingsFromLocal, + useAppDispatch, + useAppSelector, +} from "@/common"; +import { useGraphs } from "@/common/hooks"; +import { + fetchGraphDetails, + reset, + setOptions, + setSelectedGraphId, + setTrulienceSettings, +} from "@/store/reducers/global"; + +interface AuthInitializerProps { + children: ReactNode; +} + +const AuthInitializer = (props: AuthInitializerProps) => { + const { children } = props; + const dispatch = useAppDispatch(); + const { initialize } = useGraphs(); + const selectedGraphId = useAppSelector( + (state) => state.global.selectedGraphId + ); + const graphList = useAppSelector((state) => state.global.graphList); + const urlParamApplied = useRef(false); + + useEffect(() => { + if (typeof window !== "undefined") { + const options = getOptionsFromLocal(); + const trulienceSettings = getTrulienceSettingsFromLocal(); + initialize(); + if (options && options.channel) { + dispatch(reset()); + dispatch(setOptions(options)); + dispatch(setTrulienceSettings(trulienceSettings)); + } else { + dispatch(reset()); + dispatch( + setOptions({ + channel: getRandomChannel(), + userId: getRandomUserId(), + }) + ); + } + } + }, [dispatch]); + + // Check URL params for graph selection on initial load only + useEffect(() => { + if (urlParamApplied.current) return; + if (typeof window !== "undefined" && graphList.length > 0) { + const urlParams = new URLSearchParams(window.location.search); + const graphParam = urlParams.get("graph"); + if (graphParam) { + // Find graph by name (frontend uses UUIDs for graph_id, API uses name) + const graph = graphList.find((g) => g.name === graphParam); + if (graph) { + const graphId = graph.graph_id || graph.name; + dispatch(setSelectedGraphId(graphId)); + urlParamApplied.current = true; + } + } + } + }, [graphList, dispatch]); + + useEffect(() => { + if (selectedGraphId) { + const graph = graphList.find((g) => g.graph_id === selectedGraphId); + if (!graph) { + return; + } + dispatch(fetchGraphDetails(graph)); + } + }, [selectedGraphId, graphList, dispatch]); // Automatically fetch details when `selectedGraphId` changes + + return children; +}; + +export default AuthInitializer; diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/theme-provider.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/theme-provider.tsx new file mode 100644 index 0000000000..6459132f47 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/theme-provider.tsx @@ -0,0 +1,11 @@ +"use client"; + +import { ThemeProvider as NextThemesProvider } from "next-themes"; +import type * as React from "react"; + +export function ThemeProvider({ + children, + ...props +}: React.ComponentProps) { + return {children}; +} diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/ui/avatar.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/ui/avatar.tsx new file mode 100644 index 0000000000..bd40562552 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/ui/avatar.tsx @@ -0,0 +1,50 @@ +"use client"; + +import * as AvatarPrimitive from "@radix-ui/react-avatar"; +import * as React from "react"; + +import { cn } from "@/lib/utils"; + +const Avatar = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +Avatar.displayName = AvatarPrimitive.Root.displayName; + +const AvatarImage = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AvatarImage.displayName = AvatarPrimitive.Image.displayName; + +const AvatarFallback = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName; + +export { Avatar, AvatarImage, AvatarFallback }; diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/ui/button.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/ui/button.tsx new file mode 100644 index 0000000000..a109e272d5 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/ui/button.tsx @@ -0,0 +1,57 @@ +import { Slot } from "@radix-ui/react-slot"; +import { cva, type VariantProps } from "class-variance-authority"; +import * as React from "react"; + +import { cn } from "@/lib/utils"; + +const buttonVariants = cva( + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md font-medium text-sm transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", + { + variants: { + variant: { + default: + "bg-primary text-primary-foreground shadow-sm hover:bg-primary/90", + destructive: + "bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90", + outline: + "border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground", + secondary: + "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-9 px-4 py-2", + sm: "h-8 rounded-md px-3 text-xs", + lg: "h-10 rounded-md px-8", + icon: "h-9 w-9", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +); + +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean; +} + +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button"; + return ( + + ); + } +); +Button.displayName = "Button"; + +export { Button, buttonVariants }; diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/ui/card.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/ui/card.tsx new file mode 100644 index 0000000000..8848781b75 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/ui/card.tsx @@ -0,0 +1,83 @@ +import * as React from "react"; + +import { cn } from "@/lib/utils"; + +const Card = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)); +Card.displayName = "Card"; + +const CardHeader = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)); +CardHeader.displayName = "CardHeader"; + +const CardTitle = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)); +CardTitle.displayName = "CardTitle"; + +const CardDescription = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)); +CardDescription.displayName = "CardDescription"; + +const CardContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)); +CardContent.displayName = "CardContent"; + +const CardFooter = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)); +CardFooter.displayName = "CardFooter"; + +export { + Card, + CardHeader, + CardFooter, + CardTitle, + CardDescription, + CardContent, +}; diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/ui/checkbox.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/ui/checkbox.tsx new file mode 100644 index 0000000000..c6b7d780b4 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/ui/checkbox.tsx @@ -0,0 +1,30 @@ +"use client"; + +import * as CheckboxPrimitive from "@radix-ui/react-checkbox"; +import { Check } from "lucide-react"; +import * as React from "react"; + +import { cn } from "@/lib/utils"; + +const Checkbox = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + + + +)); +Checkbox.displayName = CheckboxPrimitive.Root.displayName; + +export { Checkbox }; diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/ui/dialog.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/ui/dialog.tsx new file mode 100644 index 0000000000..b9455c0cbf --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/ui/dialog.tsx @@ -0,0 +1,122 @@ +"use client"; + +import * as DialogPrimitive from "@radix-ui/react-dialog"; +import { X } from "lucide-react"; +import * as React from "react"; + +import { cn } from "@/lib/utils"; + +const Dialog = DialogPrimitive.Root; + +const DialogTrigger = DialogPrimitive.Trigger; + +const DialogPortal = DialogPrimitive.Portal; + +const DialogClose = DialogPrimitive.Close; + +const DialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DialogOverlay.displayName = DialogPrimitive.Overlay.displayName; + +const DialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + {children} + + + Close + + + +)); +DialogContent.displayName = DialogPrimitive.Content.displayName; + +const DialogHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+); +DialogHeader.displayName = "DialogHeader"; + +const DialogFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+); +DialogFooter.displayName = "DialogFooter"; + +const DialogTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DialogTitle.displayName = DialogPrimitive.Title.displayName; + +const DialogDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DialogDescription.displayName = DialogPrimitive.Description.displayName; + +export { + Dialog, + DialogPortal, + DialogOverlay, + DialogTrigger, + DialogClose, + DialogContent, + DialogHeader, + DialogFooter, + DialogTitle, + DialogDescription, +}; diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/ui/dropdown.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/ui/dropdown.tsx new file mode 100644 index 0000000000..60114610a9 --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/ui/dropdown.tsx @@ -0,0 +1,127 @@ +"use client"; + +import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"; +import { CheckIcon, ChevronRightIcon } from "lucide-react"; +import * as React from "react"; +import { cn } from "@/lib/utils"; + +const DropdownMenu = DropdownMenuPrimitive.Root; + +const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger; + +const DropdownMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, align = "start", sideOffset = 4, ...props }, ref) => ( + + + +)); +DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName; + +const DropdownMenuItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + icon?: React.ReactNode; // Allow passing a custom icon + } +>(({ className, children, icon, ...props }, ref) => ( + + {children} +
{icon}
+
+)); +DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName; + +const DropdownMenuSub = DropdownMenuPrimitive.Sub; + +const DropdownMenuSubTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + icon?: React.ReactNode; // Allow passing a custom icon + } +>(({ className, children, icon, ...props }, ref) => ( + + {children} +
{icon}
+
+)); +DropdownMenuSubTrigger.displayName = + DropdownMenuPrimitive.SubTrigger.displayName; + +const DropdownMenuSubContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, sideOffset = 0, ...props }, ref) => ( + + + +)); +DropdownMenuSubContent.displayName = + DropdownMenuPrimitive.SubContent.displayName; + +const DropdownMenuPortal = DropdownMenuPrimitive.Portal; + +const DropdownMenuCheckboxItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, checked, children, ...props }, ref) => ( + + {children} + + {checked && } + + +)); +DropdownMenuCheckboxItem.displayName = + DropdownMenuPrimitive.CheckboxItem.displayName; + +export { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSub, + DropdownMenuSubTrigger, + DropdownMenuSubContent, + DropdownMenuPortal, + DropdownMenuCheckboxItem, +}; diff --git a/ai_agents/agents/examples/doodler/frontend/src/components/ui/form.tsx b/ai_agents/agents/examples/doodler/frontend/src/components/ui/form.tsx new file mode 100644 index 0000000000..6fc2a9cacd --- /dev/null +++ b/ai_agents/agents/examples/doodler/frontend/src/components/ui/form.tsx @@ -0,0 +1,178 @@ +"use client"; + +import type * as LabelPrimitive from "@radix-ui/react-label"; +import { Slot } from "@radix-ui/react-slot"; +import * as React from "react"; +import { + Controller, + type ControllerProps, + type FieldPath, + type FieldValues, + FormProvider, + useFormContext, +} from "react-hook-form"; +import { Label } from "@/components/ui/label"; +import { cn } from "@/lib/utils"; + +const Form = FormProvider; + +type FormFieldContextValue< + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath, +> = { + name: TName; +}; + +const FormFieldContext = React.createContext( + {} as FormFieldContextValue +); + +const FormField = < + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath, +>({ + ...props +}: ControllerProps) => { + return ( + + + + ); +}; + +const useFormField = () => { + const fieldContext = React.useContext(FormFieldContext); + const itemContext = React.useContext(FormItemContext); + const { getFieldState, formState } = useFormContext(); + + const fieldState = getFieldState(fieldContext.name, formState); + + if (!fieldContext) { + throw new Error("useFormField should be used within "); + } + + const { id } = itemContext; + + return { + id, + name: fieldContext.name, + formItemId: `${id}-form-item`, + formDescriptionId: `${id}-form-item-description`, + formMessageId: `${id}-form-item-message`, + ...fieldState, + }; +}; + +type FormItemContextValue = { + id: string; +}; + +const FormItemContext = React.createContext( + {} as FormItemContextValue +); + +const FormItem = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + const id = React.useId(); + + return ( + +
+ + ); +}); +FormItem.displayName = "FormItem"; + +const FormLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => { + const { error, formItemId } = useFormField(); + + return ( +