diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000..c9bda883fa Binary files /dev/null and b/.DS_Store differ diff --git a/.env.example b/.env.example new file mode 100644 index 0000000000..aa1bfa1315 --- /dev/null +++ b/.env.example @@ -0,0 +1,55 @@ +# Domain +# This would be set to the production domain with an env var on deployment +# used by Traefik to transmit traffic and acquire TLS certificates +DOMAIN=localhost +# To test the local Traefik config +# DOMAIN=localhost.tiangolo.com + +# Used by the backend to generate links in emails to the frontend +FRONTEND_HOST=http://localhost:5173 +# In staging and production, set this env var to the frontend host, e.g. +# FRONTEND_HOST=https://dashboard.example.com + +# Environment: local, staging, production +ENVIRONMENT=local + +PROJECT_NAME="Full Stack FastAPI Project" +STACK_NAME=full-stack-fastapi-project + +# Backend +BACKEND_CORS_ORIGINS="http://localhost,http://localhost:5173,https://localhost,https://localhost:5173,http://localhost.tiangolo.com" +SECRET_KEY=changethis +FIRST_SUPERUSER=admin@example.com +FIRST_SUPERUSER_PASSWORD=changethis + +# Emails +SMTP_HOST= +SMTP_USER= +SMTP_PASSWORD= +EMAILS_FROM_EMAIL=info@example.com +SMTP_TLS=True +SMTP_SSL=False +SMTP_PORT=587 + +# Postgres +POSTGRES_SERVER=localhost +POSTGRES_PORT=5432 +POSTGRES_DB=app +POSTGRES_USER=postgres +POSTGRES_PASSWORD=changethis + +SENTRY_DSN= + +# Configure these with your own Docker registry images +DOCKER_IMAGE_BACKEND=backend +DOCKER_IMAGE_FRONTEND=frontend + +# Razorpay Payment Gateway Configuration +# Get your API keys from: https://dashboard.razorpay.com/app/keys +# Test keys are available immediately (no KYC required) +# Live keys require KYC verification (1-2 working days) +RAZORPAY_KEY_ID=rzp_test_xxxxxxxxxxxxx +RAZORPAY_KEY_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxx +# Optional: For production webhook verification +# Get webhook secret from: Settings → Webhooks in Razorpay Dashboard +RAZORPAY_WEBHOOK_SECRET=your_webhook_secret_here diff --git a/.gitignore b/.gitignore index a6dd346572..51917455ed 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ node_modules/ /playwright-report/ /blob-report/ /playwright/.cache/ +.env diff --git a/README.md b/README.md index afe124f3fb..d63f716e8f 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ Test Coverage +A modern, full-stack FastAPI template with React frontend, authentication, and payment gateway integration. + ## Technology Stack and Features - ⚡ [**FastAPI**](https://fastapi.tiangolo.com) for the Python backend API. @@ -23,30 +25,35 @@ - 📞 [Traefik](https://traefik.io) as a reverse proxy / load balancer. - 🚢 Deployment instructions using Docker Compose, including how to set up a frontend Traefik proxy to handle automatic HTTPS certificates. - 🏭 CI (continuous integration) and CD (continuous deployment) based on GitHub Actions. +- 💳 **Payment Gateway Integration** with Razorpay for one-time payments, webhook handling, and payment analytics. ### Dashboard Login -[![API docs](img/login.png)](https://github.com/fastapi/full-stack-fastapi-template) +[![Login](img/login.png)](https://github.com/fastapi/full-stack-fastapi-template) ### Dashboard - Admin -[![API docs](img/dashboard.png)](https://github.com/fastapi/full-stack-fastapi-template) +[![Dashboard](img/dashboard.png)](https://github.com/fastapi/full-stack-fastapi-template) ### Dashboard - Create User -[![API docs](img/dashboard-create.png)](https://github.com/fastapi/full-stack-fastapi-template) +[![Create User](img/dashboard-create.png)](https://github.com/fastapi/full-stack-fastapi-template) ### Dashboard - Items -[![API docs](img/dashboard-items.png)](https://github.com/fastapi/full-stack-fastapi-template) +[![Items](img/dashboard-items.png)](https://github.com/fastapi/full-stack-fastapi-template) ### Dashboard - User Settings -[![API docs](img/dashboard-user-settings.png)](https://github.com/fastapi/full-stack-fastapi-template) +[![User Settings](img/dashboard-user-settings.png)](https://github.com/fastapi/full-stack-fastapi-template) ### Dashboard - Dark Mode -[![API docs](img/dashboard-dark.png)](https://github.com/fastapi/full-stack-fastapi-template) +[![Dark Mode](img/dashboard-dark.png)](https://github.com/fastapi/full-stack-fastapi-template) + +### Payment Checkout + +[![Payment Checkout](img/checkout.png)](https://github.com/fastapi/full-stack-fastapi-template) ### Interactive API Documentation @@ -140,6 +147,53 @@ You can (and should) pass these as environment variables from secrets. Read the [deployment.md](./deployment.md) docs for more details. +## Payment Integration (Razorpay) + +This template now includes Razorpay payment gateway integration for accepting one-time payments. + +### Setup + +1. **Create Razorpay Account**: Sign up at [https://dashboard.razorpay.com/signup](https://dashboard.razorpay.com/signup) +2. **Get API Keys**: Navigate to Settings → API Keys in Razorpay Dashboard +3. **Configure Environment Variables**: Add to `.env`: + ```bash + RAZORPAY_KEY_ID=rzp_test_xxxxxxxxxxxxx + RAZORPAY_KEY_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxx + RAZORPAY_WEBHOOK_SECRET=your_webhook_secret_here # Optional for production + ``` + +### Features + +- **Order Creation**: Backend creates Razorpay orders and saves to database +- **Payment Verification**: Secure signature verification for payment confirmation +- **Webhook Handling**: Real-time payment status updates via webhooks +- **Frontend Integration**: React components for checkout, success, and failure pages +- **Payment Analytics**: Dashboard showing payment history and statistics +- **Database Models**: Order and Payment models with proper relationships + +### API Endpoints + +- `POST /api/v1/payments/create-order` - Create payment order (requires auth) +- `POST /api/v1/payments/verify` - Verify payment signature (requires auth) +- `POST /api/v1/payments/webhook` - Razorpay webhook handler (public, signature verified) +- `GET /api/v1/payments/orders` - List user orders (requires auth) +- `GET /api/v1/payments/orders/{order_id}` - Get order details (requires auth) + +### Database Schema + +New tables added: +- `order` - Stores payment orders with Razorpay order IDs +- `payment` - Stores payment records linked to orders + +Migrations are handled automatically via Alembic. See [backend/README.md](./backend/README.md#database-migrations-with-alembic) for details. + +### Documentation + +For detailed setup and configuration: +- Payment API details: [backend/README.md](./backend/README.md#payment-api-endpoints) +- Database migrations: [backend/README.md](./backend/README.md#database-migrations-with-alembic) +- Development guide: [development.md](./development.md) + ### Generate Secret Keys Some environment variables in the `.env` file have a default value of `changethis`. diff --git a/backend/app/alembic/versions/7c4cf1d2308a_add_payment_models.py b/backend/app/alembic/versions/7c4cf1d2308a_add_payment_models.py new file mode 100644 index 0000000000..5dd77c850e --- /dev/null +++ b/backend/app/alembic/versions/7c4cf1d2308a_add_payment_models.py @@ -0,0 +1,61 @@ +"""Add payment models + +Revision ID: 7c4cf1d2308a +Revises: 1a31ce608336 +Create Date: 2024-11-02 12:10:28.000000 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql +import sqlmodel.sql.sqltypes + +# revision identifiers, used by Alembic. +revision = '7c4cf1d2308a' +down_revision = '1a31ce608336' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('order', + sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False), + sa.Column('amount', sa.Numeric(precision=19, scale=2), nullable=False), + sa.Column('currency', sa.String(length=3), nullable=False), + sa.Column('receipt', sa.String(length=255), nullable=True), + sa.Column('notes', postgresql.JSON(astext_type=sa.Text()), nullable=True), + sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False), + sa.Column('razorpay_order_id', sa.String(length=255), nullable=False), + sa.Column('status', sa.String(length=50), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_index(op.f('ix_order_razorpay_order_id'), 'order', ['razorpay_order_id'], unique=True) + op.create_table('payment', + sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False), + sa.Column('order_id', postgresql.UUID(as_uuid=True), nullable=False), + sa.Column('razorpay_payment_id', sa.String(length=255), nullable=False), + sa.Column('razorpay_signature', sa.String(length=500), nullable=True), + sa.Column('status', sa.String(length=50), nullable=False), + sa.Column('amount', sa.Numeric(precision=19, scale=2), nullable=False), + sa.Column('currency', sa.String(length=3), nullable=False), + sa.Column('method', sa.String(length=50), nullable=True), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['order_id'], ['order.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.create_index(op.f('ix_payment_razorpay_payment_id'), 'payment', ['razorpay_payment_id'], unique=True) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index(op.f('ix_payment_razorpay_payment_id'), table_name='payment') + op.drop_table('payment') + op.drop_index(op.f('ix_order_razorpay_order_id'), table_name='order') + op.drop_table('order') + # ### end Alembic commands ### + diff --git a/backend/app/api/main.py b/backend/app/api/main.py index eac18c8e8f..cc1df15522 100644 --- a/backend/app/api/main.py +++ b/backend/app/api/main.py @@ -1,6 +1,6 @@ from fastapi import APIRouter -from app.api.routes import items, login, private, users, utils +from app.api.routes import items, login, payments, private, users, utils from app.core.config import settings api_router = APIRouter() @@ -8,6 +8,7 @@ api_router.include_router(users.router) api_router.include_router(utils.router) api_router.include_router(items.router) +api_router.include_router(payments.router) if settings.ENVIRONMENT == "local": diff --git a/backend/app/api/routes/__init__.py b/backend/app/api/routes/__init__.py index e69de29bb2..f626027343 100644 --- a/backend/app/api/routes/__init__.py +++ b/backend/app/api/routes/__init__.py @@ -0,0 +1,2 @@ +from . import payments + diff --git a/backend/app/api/routes/payments.py b/backend/app/api/routes/payments.py new file mode 100644 index 0000000000..d1a9267493 --- /dev/null +++ b/backend/app/api/routes/payments.py @@ -0,0 +1,390 @@ +"""Payment API routes for Razorpay integration.""" + +import uuid +from typing import Any + +from fastapi import APIRouter, HTTPException, Request, status +from fastapi.responses import JSONResponse + +from app.api.deps import CurrentUser, SessionDep +from app.core.config import settings +from app.crud import ( + create_order as crud_create_order, + create_payment, + get_order_by_id, + get_order_by_razorpay_id, + get_payments_by_order, + get_user_orders, + update_order_status, +) +from app.models import ( + Message, + OrderCreate, + OrderCreateRequest, + OrderCreateResponse, + OrderPublic, + OrdersPublic, + PaymentCreate, + PaymentPublic, + PaymentVerifyRequest, + PaymentVerifyResponse, +) +from app.services.razorpay_service import RazorpayClient, get_razorpay_client + +router = APIRouter(prefix="/payments", tags=["payments"]) + + +@router.post("/create-order", response_model=OrderCreateResponse, status_code=status.HTTP_201_CREATED) +def create_order( + *, session: SessionDep, current_user: CurrentUser, order_in: OrderCreateRequest +) -> Any: + """ + Create a Razorpay order for payment. + + This endpoint creates an order on Razorpay and saves it to the database. + Returns order details including Razorpay Key ID for frontend integration. + """ + if not settings.razorpay_enabled: + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="Payment service is not configured. Please set RAZORPAY_KEY_ID and RAZORPAY_KEY_SECRET.", + ) + + try: + # Create Razorpay order + razorpay_client = get_razorpay_client() + razorpay_order = razorpay_client.create_order( + amount=order_in.amount, + currency=order_in.currency, + receipt=order_in.receipt, + notes=order_in.notes, + ) + + # Save order to database + order_create = OrderCreate( + amount=order_in.amount, + currency=order_in.currency, + receipt=order_in.receipt, + notes=order_in.notes, + ) + crud_create_order( + session=session, + order_in=order_create, + user_id=current_user.id, + razorpay_order_id=razorpay_order["id"], + ) + + # Return response with Razorpay key for frontend + return OrderCreateResponse( + id=razorpay_order["id"], + order_id=razorpay_order["id"], + amount=razorpay_order["amount"], + currency=razorpay_order["currency"], + key=settings.RAZORPAY_KEY_ID, + ) + except ValueError as e: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=str(e), + ) from e + except Exception as e: + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Failed to create order: {str(e)}", + ) from e + + +@router.post("/verify", response_model=PaymentVerifyResponse) +def verify_payment( + *, session: SessionDep, current_user: CurrentUser, payment_in: PaymentVerifyRequest +) -> Any: + """ + Verify payment signature and save payment record. + + After Razorpay checkout, this endpoint verifies the payment signature + and creates a payment record in the database. + """ + if not settings.razorpay_enabled: + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="Payment service is not configured.", + ) + + try: + # Get order from database + order = get_order_by_razorpay_id( + session=session, razorpay_order_id=payment_in.razorpay_order_id + ) + if not order: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Order not found", + ) + + # Verify user owns the order + if order.user_id != current_user.id and not current_user.is_superuser: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="Not enough permissions", + ) + + # Verify payment signature + razorpay_client = get_razorpay_client() + is_valid = razorpay_client.verify_payment_signature( + order_id=payment_in.razorpay_order_id, + payment_id=payment_in.razorpay_payment_id, + signature=payment_in.razorpay_signature, + ) + + if not is_valid: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="Invalid payment signature", + ) + + # Get payment details from Razorpay + razorpay_order_data = razorpay_client.get_order(payment_in.razorpay_order_id) + payment_amount = int(razorpay_order_data.get("amount", order.amount)) + payment_currency = razorpay_order_data.get("currency", order.currency) + + # Create or update payment record + payment_create = PaymentCreate( + order_id=order.id, + razorpay_payment_id=payment_in.razorpay_payment_id, + razorpay_signature=payment_in.razorpay_signature, + amount=payment_amount, + currency=payment_currency, + method=None, # Can be updated from webhook + status="captured", + ) + payment = create_payment(session=session, payment_in=payment_create) + + # Update order status + update_order_status(session=session, order=order, status="paid") + + return PaymentVerifyResponse( + success=True, + order=OrderPublic.model_validate(order), + payment=PaymentPublic.model_validate(payment), + ) + except HTTPException: + raise + except ValueError as e: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=str(e), + ) from e + except Exception as e: + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Failed to verify payment: {str(e)}", + ) from e + + +@router.post("/webhook") +async def webhook_handler(request: Request, session: SessionDep) -> JSONResponse: + """ + Handle Razorpay webhook events. + + This endpoint receives webhook notifications from Razorpay + and updates payment and order status accordingly. + """ + if not settings.razorpay_enabled: + return JSONResponse( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + content={"message": "Payment service is not configured"}, + ) + + try: + # Get webhook payload + payload_bytes = await request.body() + payload_str = payload_bytes.decode("utf-8") + webhook_data = await request.json() + + # Get signature from headers + signature = request.headers.get("X-Razorpay-Signature") + if not signature: + return JSONResponse( + status_code=status.HTTP_400_BAD_REQUEST, + content={"message": "Missing webhook signature"}, + ) + + # Verify webhook signature + razorpay_client = get_razorpay_client() + is_valid = razorpay_client.verify_webhook_signature(payload_str, signature) + + if not is_valid: + return JSONResponse( + status_code=status.HTTP_400_BAD_REQUEST, + content={"message": "Invalid webhook signature"}, + ) + + # Process webhook event + event = webhook_data.get("event") + payload = webhook_data.get("payload", {}) + + if event == "payment.authorized": + payment_data = payload.get("payment", {}).get("entity", {}) + order_data = payload.get("order", {}).get("entity", {}) + + # Find order + razorpay_order_id = order_data.get("id") + if razorpay_order_id: + order = get_order_by_razorpay_id( + session=session, razorpay_order_id=razorpay_order_id + ) + if order: + # Create or update payment + payment_id = payment_data.get("id") + if payment_id: + existing_payments = get_payments_by_order( + session=session, order_id=order.id + ) + existing_payment = next( + (p for p in existing_payments if p.razorpay_payment_id == payment_id), + None, + ) + + if not existing_payment: + payment_create = PaymentCreate( + order_id=order.id, + razorpay_payment_id=payment_id, + razorpay_signature=None, + amount=int(payment_data.get("amount", 0)), + currency=payment_data.get("currency", "INR"), + method=payment_data.get("method"), + status="authorized", + ) + create_payment(session=session, payment_in=payment_create) + + elif event == "payment.captured": + payment_data = payload.get("payment", {}).get("entity", {}) + order_data = payload.get("order", {}).get("entity", {}) + + razorpay_order_id = order_data.get("id") + payment_id = payment_data.get("id") + + if razorpay_order_id and payment_id: + order = get_order_by_razorpay_id( + session=session, razorpay_order_id=razorpay_order_id + ) + if order: + # Update order status + update_order_status(session=session, order=order, status="paid") + + # Update or create payment + existing_payments = get_payments_by_order( + session=session, order_id=order.id + ) + existing_payment = next( + (p for p in existing_payments if p.razorpay_payment_id == payment_id), + None, + ) + + if existing_payment: + existing_payment.status = "captured" + existing_payment.method = payment_data.get("method") + session.add(existing_payment) + session.commit() + else: + payment_create = PaymentCreate( + order_id=order.id, + razorpay_payment_id=payment_id, + razorpay_signature=None, + amount=int(payment_data.get("amount", 0)), + currency=payment_data.get("currency", "INR"), + method=payment_data.get("method"), + status="captured", + ) + create_payment(session=session, payment_in=payment_create) + + elif event == "payment.failed": + payment_data = payload.get("payment", {}).get("entity", {}) + order_data = payload.get("order", {}).get("entity", {}) + + razorpay_order_id = order_data.get("id") + payment_id = payment_data.get("id") + + if razorpay_order_id and payment_id: + order = get_order_by_razorpay_id( + session=session, razorpay_order_id=razorpay_order_id + ) + if order: + # Update order status + update_order_status(session=session, order=order, status="failed") + + # Update or create payment + existing_payments = get_payments_by_order( + session=session, order_id=order.id + ) + existing_payment = next( + (p for p in existing_payments if p.razorpay_payment_id == payment_id), + None, + ) + + if existing_payment: + existing_payment.status = "failed" + session.add(existing_payment) + session.commit() + else: + payment_create = PaymentCreate( + order_id=order.id, + razorpay_payment_id=payment_id, + razorpay_signature=None, + amount=int(payment_data.get("amount", 0)), + currency=payment_data.get("currency", "INR"), + method=payment_data.get("method"), + status="failed", + ) + create_payment(session=session, payment_in=payment_create) + + return JSONResponse( + status_code=status.HTTP_200_OK, + content={"message": "Webhook processed successfully"}, + ) + except Exception as e: + # Log error but return 200 to prevent Razorpay from retrying + return JSONResponse( + status_code=status.HTTP_200_OK, + content={"message": f"Webhook processing error: {str(e)}"}, + ) + + +@router.get("/orders", response_model=OrdersPublic) +def read_orders( + session: SessionDep, current_user: CurrentUser, skip: int = 0, limit: int = 100 +) -> Any: + """ + Retrieve paginated list of orders for the current user. + """ + orders, count = get_user_orders( + session=session, user_id=current_user.id, skip=skip, limit=limit + ) + return OrdersPublic( + data=[OrderPublic.model_validate(order) for order in orders], + count=count, + ) + + +@router.get("/orders/{order_id}", response_model=OrderPublic) +def read_order( + session: SessionDep, current_user: CurrentUser, order_id: uuid.UUID +) -> Any: + """ + Get order details by ID. + + Users can only access their own orders unless they are superusers. + """ + order = get_order_by_id(session=session, order_id=order_id) + if not order: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Order not found", + ) + if not current_user.is_superuser and order.user_id != current_user.id: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="Not enough permissions", + ) + return OrderPublic.model_validate(order) + diff --git a/backend/app/core/config.py b/backend/app/core/config.py index 6a8ca50bb1..4faa887219 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -94,6 +94,16 @@ def emails_enabled(self) -> bool: FIRST_SUPERUSER: EmailStr FIRST_SUPERUSER_PASSWORD: str + # Razorpay Payment Gateway Configuration + RAZORPAY_KEY_ID: str = "" + RAZORPAY_KEY_SECRET: str = "" + RAZORPAY_WEBHOOK_SECRET: str | None = None + + @computed_field # type: ignore[prop-decorator] + @property + def razorpay_enabled(self) -> bool: + return bool(self.RAZORPAY_KEY_ID and self.RAZORPAY_KEY_SECRET) + def _check_default_secret(self, var_name: str, value: str | None) -> None: if value == "changethis": message = ( @@ -112,6 +122,17 @@ def _enforce_non_default_secrets(self) -> Self: self._check_default_secret( "FIRST_SUPERUSER_PASSWORD", self.FIRST_SUPERUSER_PASSWORD ) + # Warn if Razorpay keys are not set in production + if ( + self.ENVIRONMENT != "local" + and not self.razorpay_enabled + and self.RAZORPAY_KEY_ID == "" + ): + warnings.warn( + "RAZORPAY_KEY_ID and RAZORPAY_KEY_SECRET are not set. " + "Payment functionality will be disabled.", + stacklevel=1, + ) return self diff --git a/backend/app/crud.py b/backend/app/crud.py index 905bf48724..ee1902d1aa 100644 --- a/backend/app/crud.py +++ b/backend/app/crud.py @@ -1,10 +1,20 @@ import uuid from typing import Any -from sqlmodel import Session, select +from sqlmodel import Session, func, select from app.core.security import get_password_hash, verify_password -from app.models import Item, ItemCreate, User, UserCreate, UserUpdate +from app.models import ( + Item, + ItemCreate, + Order, + OrderCreate, + Payment, + PaymentCreate, + User, + UserCreate, + UserUpdate, +) def create_user(*, session: Session, user_create: UserCreate) -> User: @@ -52,3 +62,149 @@ def create_item(*, session: Session, item_in: ItemCreate, owner_id: uuid.UUID) - session.commit() session.refresh(db_item) return db_item + + +# Payment CRUD functions +def create_order( + *, session: Session, order_in: OrderCreate, user_id: uuid.UUID, razorpay_order_id: str +) -> Order: + """ + Create an order in the database. + + Args: + session: Database session + order_in: Order creation data + user_id: User ID who created the order + razorpay_order_id: Razorpay order ID + + Returns: + Created Order object + """ + db_order = Order.model_validate( + order_in, update={"user_id": user_id, "razorpay_order_id": razorpay_order_id, "status": "created"} + ) + session.add(db_order) + session.commit() + session.refresh(db_order) + return db_order + + +def get_order_by_id(*, session: Session, order_id: uuid.UUID) -> Order | None: + """ + Get order by UUID. + + Args: + session: Database session + order_id: Order UUID + + Returns: + Order object or None if not found + """ + return session.get(Order, order_id) + + +def get_order_by_razorpay_id( + *, session: Session, razorpay_order_id: str +) -> Order | None: + """ + Get order by Razorpay order ID. + + Args: + session: Database session + razorpay_order_id: Razorpay order ID + + Returns: + Order object or None if not found + """ + statement = select(Order).where(Order.razorpay_order_id == razorpay_order_id) + return session.exec(statement).first() + + +def update_order_status( + *, session: Session, order: Order, status: str +) -> Order: + """ + Update order status. + + Args: + session: Database session + order: Order object to update + status: New status + + Returns: + Updated Order object + """ + from datetime import datetime + order.status = status + order.updated_at = datetime.utcnow() + session.add(order) + session.commit() + session.refresh(order) + return order + + +def create_payment(*, session: Session, payment_in: PaymentCreate) -> Payment: + """ + Create a payment record in the database. + + Args: + session: Database session + payment_in: Payment creation data + + Returns: + Created Payment object + """ + db_payment = Payment.model_validate(payment_in) + session.add(db_payment) + session.commit() + session.refresh(db_payment) + return db_payment + + +def get_payments_by_order(*, session: Session, order_id: uuid.UUID) -> list[Payment]: + """ + Get all payments for an order. + + Args: + session: Database session + order_id: Order UUID + + Returns: + List of Payment objects + """ + statement = select(Payment).where(Payment.order_id == order_id) + return list(session.exec(statement).all()) + + +def get_user_orders( + *, session: Session, user_id: uuid.UUID, skip: int = 0, limit: int = 100 +) -> tuple[list[Order], int]: + """ + Get paginated list of orders for a user. + + Args: + session: Database session + user_id: User UUID + skip: Number of records to skip + limit: Maximum number of records to return + + Returns: + Tuple of (list of Order objects, total count) + """ + count_statement = ( + select(func.count()) + .select_from(Order) + .where(Order.user_id == user_id) + ) + count = session.exec(count_statement).one() + + statement = ( + select(Order) + .where(Order.user_id == user_id) + .order_by(Order.created_at.desc()) + .offset(skip) + .limit(limit) + ) + orders = list(session.exec(statement).all()) + + return orders, count diff --git a/backend/app/models.py b/backend/app/models.py index 2d060ba0b4..242d00f33d 100644 --- a/backend/app/models.py +++ b/backend/app/models.py @@ -1,7 +1,10 @@ import uuid +from datetime import datetime +from decimal import Decimal from pydantic import EmailStr -from sqlmodel import Field, Relationship, SQLModel +from sqlmodel import Column, DateTime, Field, Relationship, SQLModel +from sqlalchemy import JSON, Numeric # Shared properties @@ -44,6 +47,7 @@ class User(UserBase, table=True): id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) hashed_password: str items: list["Item"] = Relationship(back_populates="owner", cascade_delete=True) + orders: list["Order"] = Relationship(back_populates="owner", cascade_delete=True) # Properties to return via API, id is always required @@ -111,3 +115,152 @@ class TokenPayload(SQLModel): class NewPassword(SQLModel): token: str new_password: str = Field(min_length=8, max_length=128) + + +# Payment Models +# Shared properties for Order +class OrderBase(SQLModel): + amount: Decimal = Field(gt=0, description="Amount in smallest currency unit (paise for INR)") + currency: str = Field(default="INR", max_length=3) + receipt: str | None = Field(default=None, max_length=255) + notes: dict[str, str] | None = None + + +# Properties to receive via API on order creation +class OrderCreate(OrderBase): + pass + + +# Properties to receive via API for order creation request +class OrderCreateRequest(SQLModel): + amount: int = Field(gt=0, description="Amount in smallest currency unit (paise for INR)") + currency: str = Field(default="INR", max_length=3) + receipt: str | None = Field(default=None, max_length=255) + notes: dict[str, str] | None = None + + +# Database model for Order +class Order(OrderBase, table=True): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + user_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + razorpay_order_id: str = Field(unique=True, index=True, max_length=255) + status: str = Field( + default="pending", + max_length=50, + description="Order status: pending, created, paid, failed, cancelled", + ) + created_at: datetime = Field( + default_factory=datetime.utcnow, + sa_column=Column(DateTime(timezone=False)), + ) + updated_at: datetime = Field( + default_factory=datetime.utcnow, + sa_column=Column(DateTime(timezone=False)), + ) + owner: "User" = Relationship(back_populates="orders") + payments: list["Payment"] = Relationship(back_populates="order", cascade_delete=True) + + # Override amount to use Numeric type in database + amount: Decimal = Field( + sa_column=Column(Numeric(precision=19, scale=2)), + gt=0, + ) + + # Override notes to use JSON type in database + notes: dict[str, str] | None = Field( + default=None, + sa_column=Column(JSON), + ) + + +# Properties to return via API +class OrderPublic(OrderBase): + id: uuid.UUID + user_id: uuid.UUID + razorpay_order_id: str + status: str + created_at: datetime + updated_at: datetime + + +class OrderUpdate(SQLModel): + status: str | None = Field(default=None, max_length=50) + notes: dict[str, str] | None = None + + +class OrdersPublic(SQLModel): + data: list[OrderPublic] + count: int + + +# Shared properties for Payment +class PaymentBase(SQLModel): + razorpay_payment_id: str = Field(max_length=255) + amount: Decimal = Field(gt=0) + currency: str = Field(max_length=3) + method: str | None = Field(default=None, max_length=50) + + +# Properties to receive via API on payment creation +class PaymentCreate(PaymentBase): + razorpay_signature: str | None = Field(default=None, max_length=500) + order_id: uuid.UUID + + +# Properties to receive via API for payment verification +class PaymentVerifyRequest(SQLModel): + razorpay_order_id: str = Field(max_length=255) + razorpay_payment_id: str = Field(max_length=255) + razorpay_signature: str = Field(max_length=500) + + +# Database model for Payment +class Payment(PaymentBase, table=True): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + order_id: uuid.UUID = Field( + foreign_key="order.id", nullable=False, ondelete="CASCADE" + ) + razorpay_signature: str | None = Field(default=None, max_length=500) + status: str = Field( + default="pending", + max_length=50, + description="Payment status: pending, authorized, captured, failed, refunded", + ) + created_at: datetime = Field( + default_factory=datetime.utcnow, + sa_column=Column(DateTime(timezone=False)), + ) + order: "Order" = Relationship(back_populates="payments") + + # Override amount to use Numeric type in database + amount: Decimal = Field( + sa_column=Column(Numeric(precision=19, scale=2)), + gt=0, + ) + + +# Properties to return via API +class PaymentPublic(PaymentBase): + id: uuid.UUID + order_id: uuid.UUID + razorpay_signature: str | None + status: str + created_at: datetime + + +# Response for order creation +class OrderCreateResponse(SQLModel): + id: str # razorpay_order_id + order_id: str # razorpay_order_id (for backward compatibility) + amount: int # in paise + currency: str + key: str # Razorpay Key ID for frontend + + +# Response for payment verification +class PaymentVerifyResponse(SQLModel): + success: bool + order: OrderPublic + payment: PaymentPublic diff --git a/backend/app/services/__init__.py b/backend/app/services/__init__.py new file mode 100644 index 0000000000..db0f0677ef --- /dev/null +++ b/backend/app/services/__init__.py @@ -0,0 +1,2 @@ +"""Services module for external service integrations.""" + diff --git a/backend/app/services/razorpay_service.py b/backend/app/services/razorpay_service.py new file mode 100644 index 0000000000..2f4394217f --- /dev/null +++ b/backend/app/services/razorpay_service.py @@ -0,0 +1,163 @@ +"""Razorpay payment gateway service integration.""" + +from typing import Any + +import razorpay +from razorpay.errors import BadRequestError, ServerError + +from app.core.config import settings + + +class RazorpayClient: + """Wrapper for Razorpay client with payment operations.""" + + def __init__(self) -> None: + """Initialize Razorpay client with API keys from settings.""" + if not settings.razorpay_enabled: + raise ValueError( + "Razorpay keys are not configured. " + "Please set RAZORPAY_KEY_ID and RAZORPAY_KEY_SECRET in environment variables." + ) + self.client = razorpay.Client( + auth=(settings.RAZORPAY_KEY_ID, settings.RAZORPAY_KEY_SECRET) + ) + + def create_order( + self, amount: int, currency: str, receipt: str | None = None, notes: dict[str, str] | None = None + ) -> dict[str, Any]: + """ + Create a Razorpay order. + + Args: + amount: Amount in smallest currency unit (paise for INR) + currency: Currency code (default: INR) + receipt: Receipt identifier (optional) + notes: Additional notes as key-value pairs (optional) + + Returns: + Dictionary containing Razorpay order details including order_id + + Raises: + BadRequestError: If the request is invalid + ServerError: If Razorpay server returns an error + """ + try: + order_data: dict[str, Any] = { + "amount": amount, + "currency": currency, + } + if receipt: + order_data["receipt"] = receipt + if notes: + order_data["notes"] = notes + + order = self.client.order.create(data=order_data) + return order + except (BadRequestError, ServerError) as e: + raise ValueError(f"Failed to create Razorpay order: {str(e)}") from e + + def verify_payment_signature( + self, order_id: str, payment_id: str, signature: str + ) -> bool: + """ + Verify payment signature to ensure authenticity. + + Args: + order_id: Razorpay order ID + payment_id: Razorpay payment ID + signature: Payment signature from Razorpay + + Returns: + True if signature is valid, False otherwise + """ + try: + params = { + "razorpay_order_id": order_id, + "razorpay_payment_id": payment_id, + "razorpay_signature": signature, + } + self.client.utility.verify_payment_signature(params) + return True + except razorpay.errors.SignatureVerificationError: + return False + except Exception as e: + raise ValueError(f"Error verifying payment signature: {str(e)}") from e + + def get_order(self, razorpay_order_id: str) -> dict[str, Any]: + """ + Fetch order details from Razorpay. + + Args: + razorpay_order_id: Razorpay order ID + + Returns: + Dictionary containing order details + + Raises: + BadRequestError: If order not found + ServerError: If Razorpay server returns an error + """ + try: + order = self.client.order.fetch(razorpay_order_id) + return order + except (BadRequestError, ServerError) as e: + raise ValueError(f"Failed to fetch Razorpay order: {str(e)}") from e + + def capture_payment(self, payment_id: str, amount: int) -> dict[str, Any]: + """ + Capture a payment (for manual capture flow). + + Args: + payment_id: Razorpay payment ID + amount: Amount to capture in smallest currency unit + + Returns: + Dictionary containing capture details + + Raises: + BadRequestError: If capture fails + ServerError: If Razorpay server returns an error + """ + try: + capture_data = {"amount": amount} + payment = self.client.payment.capture(payment_id, capture_data) + return payment + except (BadRequestError, ServerError) as e: + raise ValueError(f"Failed to capture payment: {str(e)}") from e + + def verify_webhook_signature(self, payload: str, signature: str) -> bool: + """ + Verify webhook signature. + + Args: + payload: Webhook payload as string + signature: Webhook signature from Razorpay + + Returns: + True if signature is valid, False otherwise + """ + if not settings.RAZORPAY_WEBHOOK_SECRET: + return False + try: + self.client.utility.verify_webhook_signature( + payload, signature, settings.RAZORPAY_WEBHOOK_SECRET + ) + return True + except razorpay.errors.SignatureVerificationError: + return False + except Exception as e: + raise ValueError(f"Error verifying webhook signature: {str(e)}") from e + + +def get_razorpay_client() -> RazorpayClient: + """ + Get Razorpay client instance. + + Returns: + RazorpayClient instance + + Raises: + ValueError: If Razorpay is not configured + """ + return RazorpayClient() + diff --git a/backend/pyproject.toml b/backend/pyproject.toml index d72454c28a..d5edf826c2 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -19,6 +19,7 @@ dependencies = [ # Pin bcrypt until passlib supports the latest "bcrypt==4.3.0", "pydantic-settings<3.0.0,>=2.2.1", + "razorpay>=1.4.2", "sentry-sdk[fastapi]<2.0.0,>=1.40.6", "pyjwt<3.0.0,>=2.8.0", ] diff --git a/frontend/package.json b/frontend/package.json index 41357dadc6..adddb38a4e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -23,7 +23,8 @@ "react-dom": "^19.2.0", "react-error-boundary": "^6.0.0", "react-hook-form": "7.62.0", - "react-icons": "^5.5.0" + "react-icons": "^5.5.0", + "zod": "^4.1.12" }, "devDependencies": { "@biomejs/biome": "^2.2.4", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml new file mode 100644 index 0000000000..aac9db929c --- /dev/null +++ b/frontend/pnpm-lock.yaml @@ -0,0 +1,3914 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@chakra-ui/react': + specifier: ^3.27.0 + version: 3.28.0(@emotion/react@11.14.0(@types/react@19.2.2)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@emotion/react': + specifier: ^11.14.0 + version: 11.14.0(@types/react@19.2.2)(react@19.2.0) + '@tanstack/react-query': + specifier: ^5.90.2 + version: 5.90.5(react@19.2.0) + '@tanstack/react-query-devtools': + specifier: ^5.90.2 + version: 5.90.2(@tanstack/react-query@5.90.5(react@19.2.0))(react@19.2.0) + '@tanstack/react-router': + specifier: ^1.131.50 + version: 1.134.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + axios: + specifier: 1.12.2 + version: 1.12.2 + form-data: + specifier: 4.0.4 + version: 4.0.4 + next-themes: + specifier: ^0.4.6 + version: 0.4.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + react: + specifier: ^19.1.1 + version: 19.2.0 + react-dom: + specifier: ^19.2.0 + version: 19.2.0(react@19.2.0) + react-error-boundary: + specifier: ^6.0.0 + version: 6.0.0(react@19.2.0) + react-hook-form: + specifier: 7.62.0 + version: 7.62.0(react@19.2.0) + react-icons: + specifier: ^5.5.0 + version: 5.5.0(react@19.2.0) + zod: + specifier: ^4.1.12 + version: 4.1.12 + devDependencies: + '@biomejs/biome': + specifier: ^2.2.4 + version: 2.3.2 + '@hey-api/openapi-ts': + specifier: 0.73.0 + version: 0.73.0(typescript@5.9.3) + '@playwright/test': + specifier: 1.56.1 + version: 1.56.1 + '@tanstack/router-devtools': + specifier: ^1.131.42 + version: 1.134.4(@tanstack/react-router@1.134.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@tanstack/router-core@1.134.4)(@types/node@24.9.2)(csstype@3.1.3)(jiti@2.6.1)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(solid-js@1.9.10)(tiny-invariant@1.3.3)(tsx@4.20.6) + '@tanstack/router-plugin': + specifier: ^1.133.15 + version: 1.134.6(@tanstack/react-router@1.134.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(tsx@4.20.6)) + '@types/node': + specifier: ^24.5.2 + version: 24.9.2 + '@types/react': + specifier: ^19.1.16 + version: 19.2.2 + '@types/react-dom': + specifier: ^19.2.1 + version: 19.2.2(@types/react@19.2.2) + '@vitejs/plugin-react-swc': + specifier: ^4.1.0 + version: 4.2.0(@swc/helpers@0.5.17)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(tsx@4.20.6)) + dotenv: + specifier: ^17.2.2 + version: 17.2.3 + typescript: + specifier: ^5.2.2 + version: 5.9.3 + vite: + specifier: ^7.1.11 + version: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(tsx@4.20.6) + +packages: + + '@ark-ui/react@5.26.2': + resolution: {integrity: sha512-qB2i9AoxhXbADTo+LEphrf/mOnxJJP18ya/0lmoZ4LZ4/K7rY4gStPaj79gKJzIkLYpOO1G4sS5ycPk/Btmiig==} + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.28.5': + resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.28.5': + resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.28.5': + resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.28.5': + resolution: {integrity: sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.28.5': + resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.3': + resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-replace-supers@7.27.1': + resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.28.4': + resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.28.5': + resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-jsx@7.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.27.1': + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.27.1': + resolution: {integrity: sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.28.5': + resolution: {integrity: sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-typescript@7.28.5': + resolution: {integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.28.4': + resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.28.5': + resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + engines: {node: '>=6.9.0'} + + '@biomejs/biome@2.3.2': + resolution: {integrity: sha512-8e9tzamuDycx7fdrcJ/F/GDZ8SYukc5ud6tDicjjFqURKYFSWMl0H0iXNXZEGmcmNUmABgGuHThPykcM41INgg==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@2.3.2': + resolution: {integrity: sha512-4LECm4kc3If0JISai4c3KWQzukoUdpxy4fRzlrPcrdMSRFksR9ZoXK7JBcPuLBmd2SoT4/d7CQS33VnZpgBjew==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@2.3.2': + resolution: {integrity: sha512-jNMnfwHT4N3wi+ypRfMTjLGnDmKYGzxVr1EYAPBcauRcDnICFXN81wD6wxJcSUrLynoyyYCdfW6vJHS/IAoTDA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@2.3.2': + resolution: {integrity: sha512-2Zz4usDG1GTTPQnliIeNx6eVGGP2ry5vE/v39nT73a3cKN6t5H5XxjcEoZZh62uVZvED7hXXikclvI64vZkYqw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@2.3.2': + resolution: {integrity: sha512-amnqvk+gWybbQleRRq8TMe0rIv7GHss8mFJEaGuEZYWg1Tw14YKOkeo8h6pf1c+d3qR+JU4iT9KXnBKGON4klw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-x64-musl@2.3.2': + resolution: {integrity: sha512-gzB19MpRdTuOuLtPpFBGrV3Lq424gHyq2lFj8wfX9tvLMLdmA/R9C7k/mqBp/spcbWuHeIEKgEs3RviOPcWGBA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@2.3.2': + resolution: {integrity: sha512-8BG/vRAhFz1pmuyd24FQPhNeueLqPtwvZk6yblABY2gzL2H8fLQAF/Z2OPIc+BPIVPld+8cSiKY/KFh6k81xfA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@2.3.2': + resolution: {integrity: sha512-lCruqQlfWjhMlOdyf5pDHOxoNm4WoyY2vZ4YN33/nuZBRstVDuqPPjS0yBkbUlLEte11FbpW+wWSlfnZfSIZvg==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@2.3.2': + resolution: {integrity: sha512-6Ee9P26DTb4D8sN9nXxgbi9Dw5vSOfH98M7UlmkjKB2vtUbrRqCbZiNfryGiwnPIpd6YUoTl7rLVD2/x1CyEHQ==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + + '@chakra-ui/react@3.28.0': + resolution: {integrity: sha512-Rm9Fppqmc4NleAhNhbvE/fiA6IfSYpzRE5IQcQ39v27yFmWwSC8M1q7E5CYF36JJp1jmMG3CBPv4JRox/WESBg==} + peerDependencies: + '@emotion/react': '>=11' + react: '>=18' + react-dom: '>=18' + + '@emotion/babel-plugin@11.13.5': + resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==} + + '@emotion/cache@11.14.0': + resolution: {integrity: sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==} + + '@emotion/hash@0.9.2': + resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==} + + '@emotion/is-prop-valid@1.4.0': + resolution: {integrity: sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==} + + '@emotion/memoize@0.9.0': + resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==} + + '@emotion/react@11.14.0': + resolution: {integrity: sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==} + peerDependencies: + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + + '@emotion/serialize@1.3.3': + resolution: {integrity: sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==} + + '@emotion/sheet@1.4.0': + resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==} + + '@emotion/unitless@0.10.0': + resolution: {integrity: sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==} + + '@emotion/use-insertion-effect-with-fallbacks@1.2.0': + resolution: {integrity: sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==} + peerDependencies: + react: '>=16.8.0' + + '@emotion/utils@1.4.2': + resolution: {integrity: sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==} + + '@emotion/weak-memoize@0.4.0': + resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==} + + '@esbuild/aix-ppc64@0.25.11': + resolution: {integrity: sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.11': + resolution: {integrity: sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.11': + resolution: {integrity: sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.11': + resolution: {integrity: sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.11': + resolution: {integrity: sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.11': + resolution: {integrity: sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.11': + resolution: {integrity: sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.11': + resolution: {integrity: sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.11': + resolution: {integrity: sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.11': + resolution: {integrity: sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.11': + resolution: {integrity: sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.11': + resolution: {integrity: sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.11': + resolution: {integrity: sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.11': + resolution: {integrity: sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.11': + resolution: {integrity: sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.11': + resolution: {integrity: sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.11': + resolution: {integrity: sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.11': + resolution: {integrity: sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.11': + resolution: {integrity: sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.11': + resolution: {integrity: sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.11': + resolution: {integrity: sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.11': + resolution: {integrity: sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.25.11': + resolution: {integrity: sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.11': + resolution: {integrity: sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.11': + resolution: {integrity: sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.11': + resolution: {integrity: sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@floating-ui/core@1.7.3': + resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} + + '@floating-ui/dom@1.7.4': + resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} + + '@floating-ui/utils@0.2.10': + resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + + '@hey-api/json-schema-ref-parser@1.0.6': + resolution: {integrity: sha512-yktiFZoWPtEW8QKS65eqKwA5MTKp88CyiL8q72WynrBs/73SAaxlSWlA2zW/DZlywZ5hX1OYzrCC0wFdvO9c2w==} + engines: {node: '>= 16'} + + '@hey-api/openapi-ts@0.73.0': + resolution: {integrity: sha512-sUscR3OIGW0k9U//28Cu6BTp3XaogWMDORj9H+5Du9E5AvTT7LZbCEDvkLhebFOPkp2cZAQfd66HiZsiwssBcQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=22.10.0} + hasBin: true + peerDependencies: + typescript: ^5.5.3 + + '@internationalized/date@3.10.0': + resolution: {integrity: sha512-oxDR/NTEJ1k+UFVQElaNIk65E/Z83HK1z1WI3lQyhTtnNg4R5oVXaPzK3jcpKG8UHKDVuDQHzn+wsxSz8RP3aw==} + + '@internationalized/number@3.6.5': + resolution: {integrity: sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g==} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@jsdevtools/ono@7.1.3': + resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} + + '@pandacss/is-valid-prop@1.4.3': + resolution: {integrity: sha512-9xHAFaRGoXikp0SKUyTHdO97mjIRuGFLDqQ+zphaVeNjTIsyac+fZjOS/2jJNuTS1eybU0/ny1FZ3BpS6SkEqw==} + + '@playwright/test@1.56.1': + resolution: {integrity: sha512-vSMYtL/zOcFpvJCW71Q/OEGQb7KYBPAdKh35WNSkaZA75JlAO8ED8UN6GUNTm3drWomcbcqRPFqQbLae8yBTdg==} + engines: {node: '>=18'} + hasBin: true + + '@rolldown/pluginutils@1.0.0-beta.43': + resolution: {integrity: sha512-5Uxg7fQUCmfhax7FJke2+8B6cqgeUJUD9o2uXIKXhD+mG0mL6NObmVoi9wXEU1tY89mZKgAYA6fTbftx3q2ZPQ==} + + '@rollup/rollup-android-arm-eabi@4.52.5': + resolution: {integrity: sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.52.5': + resolution: {integrity: sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.52.5': + resolution: {integrity: sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.52.5': + resolution: {integrity: sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.52.5': + resolution: {integrity: sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.52.5': + resolution: {integrity: sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.52.5': + resolution: {integrity: sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.52.5': + resolution: {integrity: sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.52.5': + resolution: {integrity: sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.52.5': + resolution: {integrity: sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.52.5': + resolution: {integrity: sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.52.5': + resolution: {integrity: sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.52.5': + resolution: {integrity: sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.52.5': + resolution: {integrity: sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.52.5': + resolution: {integrity: sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.52.5': + resolution: {integrity: sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.52.5': + resolution: {integrity: sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openharmony-arm64@4.52.5': + resolution: {integrity: sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.52.5': + resolution: {integrity: sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.52.5': + resolution: {integrity: sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.52.5': + resolution: {integrity: sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.52.5': + resolution: {integrity: sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==} + cpu: [x64] + os: [win32] + + '@swc/core-darwin-arm64@1.14.0': + resolution: {integrity: sha512-uHPC8rlCt04nvYNczWzKVdgnRhxCa3ndKTBBbBpResOZsRmiwRAvByIGh599j+Oo6Z5eyTPrgY+XfJzVmXnN7Q==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.14.0': + resolution: {integrity: sha512-2SHrlpl68vtePRknv9shvM9YKKg7B9T13tcTg9aFCwR318QTYo+FzsKGmQSv9ox/Ua0Q2/5y2BNjieffJoo4nA==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.14.0': + resolution: {integrity: sha512-SMH8zn01dxt809svetnxpeg/jWdpi6dqHKO3Eb11u4OzU2PK7I5uKS6gf2hx5LlTbcJMFKULZiVwjlQLe8eqtg==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.14.0': + resolution: {integrity: sha512-q2JRu2D8LVqGeHkmpVCljVNltG0tB4o4eYg+dElFwCS8l2Mnt9qurMCxIeo9mgoqz0ax+k7jWtIRHktnVCbjvQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-arm64-musl@1.14.0': + resolution: {integrity: sha512-uofpVoPCEUjYIv454ZEZ3sLgMD17nIwlz2z7bsn7rl301Kt/01umFA7MscUovFfAK2IRGck6XB+uulMu6aFhKQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-x64-gnu@1.14.0': + resolution: {integrity: sha512-quTTx1Olm05fBfv66DEBuOsOgqdypnZ/1Bh3yGXWY7ANLFeeRpCDZpljD9BSjdsNdPOlwJmEUZXMHtGm3v1TZQ==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-linux-x64-musl@1.14.0': + resolution: {integrity: sha512-caaNAu+aIqT8seLtCf08i8C3/UC5ttQujUjejhMcuS1/LoCKtNiUs4VekJd2UGt+pyuuSrQ6dKl8CbCfWvWeXw==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-win32-arm64-msvc@1.14.0': + resolution: {integrity: sha512-EeW3jFlT3YNckJ6V/JnTfGcX7UHGyh6/AiCPopZ1HNaGiXVCKHPpVQZicmtyr/UpqxCXLrTgjHOvyMke7YN26A==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.14.0': + resolution: {integrity: sha512-dPai3KUIcihV5hfoO4QNQF5HAaw8+2bT7dvi8E5zLtecW2SfL3mUZipzampXq5FHll0RSCLzlrXnSx+dBRZIIQ==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.14.0': + resolution: {integrity: sha512-nm+JajGrTqUA6sEHdghDlHMNfH1WKSiuvljhdmBACW4ta4LC3gKurX2qZuiBARvPkephW9V/i5S8QPY1PzFEqg==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.14.0': + resolution: {integrity: sha512-oExhY90bes5pDTVrei0xlMVosTxwd/NMafIpqsC4dMbRYZ5KB981l/CX8tMnGsagTplj/RcG9BeRYmV6/J5m3w==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': '>=0.5.17' + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/helpers@0.5.17': + resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} + + '@swc/types@0.1.25': + resolution: {integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==} + + '@tanstack/history@1.133.28': + resolution: {integrity: sha512-B7+x7eP2FFvi3fgd3rNH9o/Eixt+pp0zCIdGhnQbAJjFrlwIKGjGnwyJjhWJ5fMQlGks/E2LdDTqEV4W9Plx7g==} + engines: {node: '>=12'} + + '@tanstack/query-core@5.90.5': + resolution: {integrity: sha512-wLamYp7FaDq6ZnNehypKI5fNvxHPfTYylE0m/ZpuuzJfJqhR5Pxg9gvGBHZx4n7J+V5Rg5mZxHHTlv25Zt5u+w==} + + '@tanstack/query-devtools@5.90.1': + resolution: {integrity: sha512-GtINOPjPUH0OegJExZ70UahT9ykmAhmtNVcmtdnOZbxLwT7R5OmRztR5Ahe3/Cu7LArEmR6/588tAycuaWb1xQ==} + + '@tanstack/react-query-devtools@5.90.2': + resolution: {integrity: sha512-vAXJzZuBXtCQtrY3F/yUNJCV4obT/A/n81kb3+YqLbro5Z2+phdAbceO+deU3ywPw8B42oyJlp4FhO0SoivDFQ==} + peerDependencies: + '@tanstack/react-query': ^5.90.2 + react: ^18 || ^19 + + '@tanstack/react-query@5.90.5': + resolution: {integrity: sha512-pN+8UWpxZkEJ/Rnnj2v2Sxpx1WFlaa9L6a4UO89p6tTQbeo+m0MS8oYDjbggrR8QcTyjKoYWKS3xJQGr3ExT8Q==} + peerDependencies: + react: ^18 || ^19 + + '@tanstack/react-router-devtools@1.134.4': + resolution: {integrity: sha512-5egZR8X02DjvuACmBni+EJoP0YkA7hRt+AMlx9cBoVhSe4mWpp5qhqOmG9F9LCRZ2goa82YJXyvas80gjH4fSQ==} + engines: {node: '>=12'} + peerDependencies: + '@tanstack/react-router': ^1.134.4 + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + + '@tanstack/react-router@1.134.4': + resolution: {integrity: sha512-AJfO4SOltCjyHKwZ+NHkDxwLj1CJQdgvmvHh8U2ikF2d4rjMlQ0bRjEpDJ8eY5AO2Z09cak/5goqNvcpRQjhfQ==} + engines: {node: '>=12'} + peerDependencies: + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + + '@tanstack/react-store@0.8.0': + resolution: {integrity: sha512-1vG9beLIuB7q69skxK9r5xiLN3ztzIPfSQSs0GfeqWGO2tGIyInZx0x1COhpx97RKaONSoAb8C3dxacWksm1ow==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@tanstack/router-core@1.134.4': + resolution: {integrity: sha512-f3lzOx3aX+z+gfVyl9D+APArwM395E7mW26A0od9QB+yOAbFnEtJ8mUDWJAY57BPR9fOCnkMEaEVx9m7eL3u4w==} + engines: {node: '>=12'} + + '@tanstack/router-devtools-core@1.134.4': + resolution: {integrity: sha512-fhRGPjJTBP/bkPr4Qf+HCI574R/cPpygbeW3AfsoJ08nhW7hePBGbDUMk0rtEwvGO5uHESQcq0un6xrrNIxtQQ==} + engines: {node: '>=12'} + peerDependencies: + '@tanstack/router-core': ^1.134.4 + csstype: ^3.0.10 + solid-js: '>=1.9.5' + tiny-invariant: ^1.3.3 + peerDependenciesMeta: + csstype: + optional: true + + '@tanstack/router-devtools@1.134.4': + resolution: {integrity: sha512-OsaHCqxxEZZ4latp4rGC0hmLer6qY4FzoaAOXSQOfgJ9eVq0sLWH5zoB8wZBbIggUuaoP066Ye9KMz8NQWx9Hw==} + engines: {node: '>=12'} + peerDependencies: + '@tanstack/react-router': ^1.134.4 + csstype: ^3.0.10 + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + peerDependenciesMeta: + csstype: + optional: true + + '@tanstack/router-generator@1.134.4': + resolution: {integrity: sha512-8qGpsNpNdSJUuaGN04osRYaW8QZBVglUvHO6zLjQyVSfyj2zUmSdSwEbsFijftiroQU3SMz7Ugc1dA8Ky9iEAA==} + engines: {node: '>=12'} + + '@tanstack/router-plugin@1.134.6': + resolution: {integrity: sha512-6XvjKepegiNEHPH4Bgt0uGVMhw4me2xSEnF8S5cJU/9mNal9n7/bdNrC/HaIkIsn0AXcKbXagvO8J6j9yH2kRg==} + engines: {node: '>=12'} + peerDependencies: + '@rsbuild/core': '>=1.0.2' + '@tanstack/react-router': ^1.134.4 + vite: '>=5.0.0 || >=6.0.0 || >=7.0.0' + vite-plugin-solid: ^2.11.10 + webpack: '>=5.92.0' + peerDependenciesMeta: + '@rsbuild/core': + optional: true + '@tanstack/react-router': + optional: true + vite: + optional: true + vite-plugin-solid: + optional: true + webpack: + optional: true + + '@tanstack/router-utils@1.133.19': + resolution: {integrity: sha512-WEp5D2gPxvlLDRXwD/fV7RXjYtqaqJNXKB/L6OyZEbT+9BG/Ib2d7oG9GSUZNNMGPGYAlhBUOi3xutySsk6rxA==} + engines: {node: '>=12'} + + '@tanstack/store@0.8.0': + resolution: {integrity: sha512-Om+BO0YfMZe//X2z0uLF2j+75nQga6TpTJgLJQBiq85aOyZNIhkCgleNcud2KQg4k4v9Y9l+Uhru3qWMPGTOzQ==} + + '@tanstack/virtual-file-routes@1.133.19': + resolution: {integrity: sha512-IKwZENsK7owmW1Lm5FhuHegY/SyQ8KqtL/7mTSnzoKJgfzhrrf9qwKB1rmkKkt+svUuy/Zw3uVEpZtUzQruWtA==} + engines: {node: '>=12'} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@24.9.2': + resolution: {integrity: sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA==} + + '@types/parse-json@4.0.2': + resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + + '@types/react-dom@19.2.2': + resolution: {integrity: sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.2': + resolution: {integrity: sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==} + + '@vitejs/plugin-react-swc@4.2.0': + resolution: {integrity: sha512-/tesahXD1qpkGC6FzMoFOJj0RyZdw9xLELOL+6jbElwmWfwOnIVy+IfpY+o9JfD9PKaR/Eyb6DNrvbXpuvA+8Q==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^4 || ^5 || ^6 || ^7 + + '@zag-js/accordion@1.26.3': + resolution: {integrity: sha512-xZgXTc4AhH0vha5zLjjSj3GZml2LFMhJnZ/F9TU0KEci7xML1U0n2ay4KydgtiEG31/A3j3LLE+vON+/N/0jAg==} + + '@zag-js/anatomy@1.26.3': + resolution: {integrity: sha512-2HL+BDX05zRtctKwrSlYEtxeLdiJZIV5SbEpqTNvbNJ9aZNxHKgg0ciEi0bYZe8qJ70TqfNfwWb2xwRamzedhg==} + + '@zag-js/angle-slider@1.26.3': + resolution: {integrity: sha512-tmOcOLiKN+5enp2YobuZkhVCWY8Q78SnGVO4tJgj+IjZ1PU/EJwipAiAXRM1Adl/6MPIwIMe2ag5g+Qi9xIDuw==} + + '@zag-js/aria-hidden@1.26.3': + resolution: {integrity: sha512-F6P7Ff4iqly4VmxBRZaJoG09QonOIlYDmMRgHH8d8vca7aBmR5InTxy3iOjCZvX3U4xFFednEARRPjncy4Vl6Q==} + + '@zag-js/async-list@1.26.3': + resolution: {integrity: sha512-rcM4E8ITSpTANSgk6QX7TKbLyewE1iHOYIJ0NKvSLqfLqSXZgjYTVbWnOmt5q3UOhR3paCbxkEtSdX2/ZCNO/A==} + + '@zag-js/auto-resize@1.26.3': + resolution: {integrity: sha512-/hIJGEHjknBnrbGjz7NqZbRGCldklJEvePMbMi5JnELZIFRCcCKnvaXwq7DS1mYODjsLqxBZRSL4y0hNxExk4Q==} + + '@zag-js/avatar@1.26.3': + resolution: {integrity: sha512-CGQunbcfHzDi1p1B51TN+sGLGaBgLTsgHpqKM8YbR385hMuULcUguOwcnx7rFBq/w79QsdrACwhz3LFlZOsyUQ==} + + '@zag-js/bottom-sheet@1.26.3': + resolution: {integrity: sha512-qhlkSmBz/Ch2piku5h7itWNO0Uit4pTlhICVb8lLf0Q17X7SNxGYW+pMKAQMlL2M4EgA9tV1z/xE1pW4R05F6A==} + + '@zag-js/carousel@1.26.3': + resolution: {integrity: sha512-zF7RD7SR/nzl2CDPIp06J3eMXbY2Vk4auMzo9R4puuGN3XSh4+KYmKRt6DH5XmkOd/fFknT3eHH2gNRlpxBaMQ==} + + '@zag-js/checkbox@1.26.3': + resolution: {integrity: sha512-7WcJChF9jKLr3e5aJfLNiMxmAA8iYt2ZEjEmmaL1KRDUyONpig9JMDX5mg4u3iXQvZdmsxCptIYHXwdYjZjr3Q==} + + '@zag-js/clipboard@1.26.3': + resolution: {integrity: sha512-Cx8oafXtujYRlBU0XA2aXb78bs3JgNVZ4ikR6cm7Qo1AMUxh7FejIBNVaWGzHxUc5XrfliKGvQzJotyrGS3GDA==} + + '@zag-js/collapsible@1.26.3': + resolution: {integrity: sha512-vPnWRHolQXdXhP0GkNMADZsBuxhLqGzv/krrJitslYOwsKebtrYz3DrIvtLwpRPsED4igzNLv1ihHPa89kaOAA==} + + '@zag-js/collection@1.26.3': + resolution: {integrity: sha512-AYiIuZZ3Fr8eVH657uKGobf6WU5t7a4f/HfFiekwfvG0U0vsySBP7eOxukMvQJDCRNEKxARW9JyDj9pl4d7T8Q==} + + '@zag-js/color-picker@1.26.3': + resolution: {integrity: sha512-qsmgl1vHIavY+wH9jHLXlVnbSn+HBbIJy9ysC1vyM1nAM8Qm1P+h1PhojxgPkVujI6QcxSBzA+YcY56ZuSUHdw==} + + '@zag-js/color-utils@1.26.3': + resolution: {integrity: sha512-II2mfISJc0xLupXHmfc5AABG0pZy0cYwn741yjlbe7orubWnFLZLmVCzLF4b0qpLzYM+c+MnRVAb/YV6t7Mw6A==} + + '@zag-js/combobox@1.26.3': + resolution: {integrity: sha512-CejmsLlKhxfSg0FkGMMS8JPGnCa3sCHv4hZrqRrBuhUJaLjiH5/VazV+WFlHEDUrSzVWUNeoYiZuqQlBWuIeCA==} + + '@zag-js/core@1.26.3': + resolution: {integrity: sha512-NU/uBGEFE5kUDJfvayZuPom/mcvJjjIytBclIO4/dCt1IBo+C1ETbpQjG/RgpfmSjfAs2G/9pQgdqobakyWU2A==} + + '@zag-js/date-picker@1.26.3': + resolution: {integrity: sha512-3JZckrr1EI01bEYfKeB4nAgI4f+bWZLQnfOq8LtiL4HnS0a31Z3DYFxk3r49X4dxg3B62j1tlb6DzdQJARaElg==} + peerDependencies: + '@internationalized/date': '>=3.0.0' + + '@zag-js/date-utils@1.26.3': + resolution: {integrity: sha512-eoWJZzFY3fkTJU7rzFcRLGCecAnJiu1/xHrB317jgHd0eCGUrgJVY2m0h+agWUCIFtt1VdvEbcf9R9rZmQm7LQ==} + peerDependencies: + '@internationalized/date': '>=3.0.0' + + '@zag-js/dialog@1.26.3': + resolution: {integrity: sha512-8fRmRdTrmX5o9IRCo9kpldlM+L4boesyU3mDYCGoCxymzUImg8Crr+8y3uUHEKFWdxnlisYfBGbC586kWaaCSQ==} + + '@zag-js/dismissable@1.26.3': + resolution: {integrity: sha512-THAzkq2KLYq7px+pdIZ4QQoRjF02nxa5WXXVyw+cv7yb+CNcemcNaPtAAIORJhKsQC+1XF1JNiT5TKrvhSprhw==} + + '@zag-js/dom-query@1.26.3': + resolution: {integrity: sha512-ZI/EzpWRDFjeSuXiHuCHwFUtFXX7ZNiBiOnsqR5AnbQSTEvYv+Oo803RRuQ+zHDpGSFyYluSnT00/zt4vskXDQ==} + + '@zag-js/editable@1.26.3': + resolution: {integrity: sha512-DdlBwOqoXbF+X0uM7k5mYxiKI4eDkX+BYar/DnEifnEgpsTkYMtl3J5B9WmuWmFtmSoTauScHQsVe3OmVCTqTA==} + + '@zag-js/file-upload@1.26.3': + resolution: {integrity: sha512-SAifHG71HmRyAUHlqj50xjMr0Ua0uDp8qOucgr7kP2xQvxp8ETfJ5LXrvf+IWv67bF4GmXgIH5Tn7OVEY6ETWQ==} + + '@zag-js/file-utils@1.26.3': + resolution: {integrity: sha512-chXv4dL4SeBdGuNvHlPRZDDsIqRZ1YHAX7kHTZhQbp8iqXSZR/XCnwnQg93b7pb6rG9P8oN+f/pYAuKfrulXbA==} + + '@zag-js/floating-panel@1.26.3': + resolution: {integrity: sha512-Xue020m4gb9K/zboeW+r6bhSzqqwQpuGqfeFqgekP1XZTxGcEBDHO330gngi6hu7gO9DEMVr1sKinJKZ5kgQ2Q==} + + '@zag-js/focus-trap@1.26.3': + resolution: {integrity: sha512-mzvt9pzZ80T7O3TDcpUc7kybuWcOEO6yWvDUbJybJsMCKMvLG3HpH14gcPGOL41YZ7RTOh5PixdML8/Xb7/5Iw==} + + '@zag-js/focus-visible@1.26.3': + resolution: {integrity: sha512-gjcOCZeVlqDsCes3z5bmVLmVJQXhs+aMFs3+1JCmOUOT9zfLQ4HLlGfoesG3Zf2h/VUiIV6oZIJDLu3t/iUSig==} + + '@zag-js/highlight-word@1.26.3': + resolution: {integrity: sha512-AylY/vZMPzN4FfZeeURlMmyvS4ytQDvAYFOGLPwJjK9zajIuP7CuIa6DtkAIvhf1hfb4oHtH4MwHA2TA2hfUAQ==} + + '@zag-js/hover-card@1.26.3': + resolution: {integrity: sha512-M6hEQHZnwx4PeGIl3GsMdGFtKvp2f+dYiDttqkhi5DCcWN4S3173mExK7MNFTgqFCGLTqX86w4eIyWRGBWrZ0Q==} + + '@zag-js/i18n-utils@1.26.3': + resolution: {integrity: sha512-wFCVuUK3/GjOryQYPbsQMKlE7LX2sFgU0JccbzrvvKLe1fBCznESWrYjPd93hA+Dm6myQYQa9maxnJ2HiVB4vA==} + + '@zag-js/interact-outside@1.26.3': + resolution: {integrity: sha512-CBTagsGQ6QXaPISc8SS1wwjdpZNgMJt3ecYCIA0FP7QwUXNSnNVq7izxXwyoSzkO6xLkXS+kiqwd9guKTUBQ0Q==} + + '@zag-js/json-tree-utils@1.26.3': + resolution: {integrity: sha512-SubdKHCnAqZAFd4H0YOCBLFS2ZKP9+eq6+sBlj/2M8hmFPltjSDQWHko5u+/RMo3nKae/FpxLu2yo4CsswKpHA==} + + '@zag-js/listbox@1.26.3': + resolution: {integrity: sha512-oeD5s8R37xTo+sXIEAb4uNzu+RxTfSdojchg7WGBQMQfbgiTyyzSpZeQ1WpvdiRNiI7RREKfCBwNDEE+EWwwHA==} + + '@zag-js/live-region@1.26.3': + resolution: {integrity: sha512-of7L/R3sdDmsRU3JhZ0azKWqveCBSsTU6yT9xDocY+m7g4MRyUtNfzaqpVDQeJI1S7BD6rGhL7podYYuRhJUvg==} + + '@zag-js/menu@1.26.3': + resolution: {integrity: sha512-92GHkFKW6PdG8DUnXlZWJskW+rjWtHUgdPUVOI94EN/+Bz7IqJ0AtVTiR9Sc/tuvxP6RRcBelD1pj+8+wVucfg==} + + '@zag-js/number-input@1.26.3': + resolution: {integrity: sha512-Ft/Ot4jJpkaTGS1wK7z9YzdKxqAAKOM8EiGFHcMufPpyGwLIxNmScXNVGTjDqdWIIW3rPPrxLtIlA4ovUe4ZsQ==} + + '@zag-js/pagination@1.26.3': + resolution: {integrity: sha512-dTuDXWx833UUzVfn0HLoTtj0SIfKr5sJl/CEyLaLLS4+GAhDYsPkkPereLSjAL3ffUoKzqkqACh17wI/IibmgQ==} + + '@zag-js/password-input@1.26.3': + resolution: {integrity: sha512-rdItTM+TnhW6Wpzt0fPhqLug0BfHUZYSK3+77gny9ZhrBH9XrPXBbHb3ORzmGZfBFuVG+bmF1shI+wg6YS/6rA==} + + '@zag-js/pin-input@1.26.3': + resolution: {integrity: sha512-4e5h3T9UirAd8+StrHJ180PComxXofg2Pc5NxYs1D73dIKRhbB03Gbbt8ONJg0Pys3HCCcMe5IMzhmmwIdTBCw==} + + '@zag-js/popover@1.26.3': + resolution: {integrity: sha512-9eohN1s5ha0mwF6AIht9SE6D0Nl40IL4BY8gL4QWiaLZPPuILqzFby7yug+USdQuMNV2sk7ow6khaU2f7DTQEQ==} + + '@zag-js/popper@1.26.3': + resolution: {integrity: sha512-rCBhh+yfMUmBKJkzFvOdeeS3z/uHgbts1lXQ9SZqHBXQ8zQNjSREdQt9E1Ge2lR+ZPtwLpS8adrUtLzLRFc7Uw==} + + '@zag-js/presence@1.26.3': + resolution: {integrity: sha512-K3jKOcqimLOGRGcywY128NRzUHeUKXVKYALA5yi/gn6EfJRbX/lV/CQGG9dRiVpI+KnpuCIgJ5zr0ojU0d27yw==} + + '@zag-js/progress@1.26.3': + resolution: {integrity: sha512-NwCjePJLEhtNypBFvHg74dtzx6TsK4+1lr/2jwDWO7/vTCLzMRa6TzHD/Tt6KJl5SlLKRSPeCRRc3pnOmKC4LA==} + + '@zag-js/qr-code@1.26.3': + resolution: {integrity: sha512-Tq3TWpECOlUmYiC+8svYaUaocBYH4/psAAl2tq4f2qQdCYsB3c20DAG/x6GaDZPf6EFPC/jSgIjCDeBZGw2g4A==} + + '@zag-js/radio-group@1.26.3': + resolution: {integrity: sha512-3JLamlpsaa5qW2BzQ6qjoSS70DV2E5YBJWdFAYIHKttQMBzxhRux0U3GR7SCVXp6C7xinR+/xxYEt4uexMK2MQ==} + + '@zag-js/rating-group@1.26.3': + resolution: {integrity: sha512-4Ki6GtCY5+su2V6080NlYtOwt+DTjvWcJ0SVPqc/TDe6FgefkHhqAlTClKWVR8hocxk5Mq0z3mgZZ/Y2Yzss9Q==} + + '@zag-js/react@1.26.3': + resolution: {integrity: sha512-Z+O89rAmpMmNTMmdLAambnnwTwsRYMAiUZe7RF5TjlLuWMtV6Nc5TpBii3fqxZ/5S9vaUMtDMb9gsHPEfOR7Kw==} + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@zag-js/rect-utils@1.26.3': + resolution: {integrity: sha512-+ayBRgNO0xo+sJmnGfZDTKxHyWj6acAUjELwlcHbT0LIxMULTPxbA+Sf1d8Zz3x4fah9v2UN6/AaIrYnldFxTQ==} + + '@zag-js/remove-scroll@1.26.3': + resolution: {integrity: sha512-vofKmcJqN9AQqH6BXOii6cIQ5wj6w4cMj0psGeMUE5Rh1Xifg6chvp6ZMX0EqlTz5pYuE9e3VLPpuWUEuY+8Hg==} + + '@zag-js/scroll-area@1.26.3': + resolution: {integrity: sha512-C35ad+q5tZkZQwgoiUwyB/HoGLiin+DBPKvKcXQjztGMTB8fv/7n0vzKdpbo5BEFV626ys8vKGV/WY9Zkjdj6w==} + + '@zag-js/scroll-snap@1.26.3': + resolution: {integrity: sha512-Pzy2p2xAYILg18Z2h8xtVZqxgcITf7igXIJEngR8Tmvg+97NBYHPgl9sp86mNdoVKkQ5FB4ohirYvHrHONIurw==} + + '@zag-js/select@1.26.3': + resolution: {integrity: sha512-4T7Y6fd8FZiTuPQWjuBNG6MWDZbVPO74BlEpBJdbDK9LEJnR2yPnDmNS855BAk0ERzw4UWBwX/HbbDDaYwiRiQ==} + + '@zag-js/signature-pad@1.26.3': + resolution: {integrity: sha512-2oO06kTt96POPkQ1VvXcfSKihHJAdGSKhIQHpi5pqPl5OWCyD7DlqVeeP+IHsoTSOIyR2w1EzEG9PCQFc9F50Q==} + + '@zag-js/slider@1.26.3': + resolution: {integrity: sha512-EIZcljXslieIz6uWe4YOUjrZbLiW5w6LFhlSfszDs4OGnyKxOImiFWEhuArPCGW7CyuyISFy1GWFW+vi5+6Y1w==} + + '@zag-js/splitter@1.26.3': + resolution: {integrity: sha512-dN4ZbOXv83bBVsDyZxBFmPB/o/0OMcOTVIdZbt7aOe1y2z/As/8omzg6zzhqrIV+ASVJwFl6R+QHMngS2NZFhQ==} + + '@zag-js/steps@1.26.3': + resolution: {integrity: sha512-eM4ytff6eo93J6AlG8OJcKZ7t5XF8SLLHDJFKIGG59GDYtK8oPSdIVkjy6Ud4XvKXhKufZJUqT7qDT8UDOHxww==} + + '@zag-js/store@1.26.3': + resolution: {integrity: sha512-mDBylMkKKobJTUCJmuLDRzZsDRBkwQFcjlyCFQa9fLAjVhfCkF2Y3lAp3MuyqeJa+c7X3BbkXDD/kL2UoiTFMg==} + + '@zag-js/switch@1.26.3': + resolution: {integrity: sha512-Fc56yuh0cIf0/8AdRtBS9YVoxIIESQiYf61QMQS/pfO8hBeSFQQmbjeAf8MyOd2QadWwoNKABCiUArP2nBl1Rg==} + + '@zag-js/tabs@1.26.3': + resolution: {integrity: sha512-3Iqb+TAw49WldJaMczyzhOQl6F/x9QBgMSp7NhE6AIMaityr0ZE3jCU0qYS+F2DPAu7ng87SOCVA0dOaO/J4eg==} + + '@zag-js/tags-input@1.26.3': + resolution: {integrity: sha512-BSzQtfx72zhs4mfBsWReY30HhnKg1KSTzCVThm8oHmkcDGvpDuUbylM2KMsQdgYWTGYHI4FiIzUsUd+RVDOAgw==} + + '@zag-js/timer@1.26.3': + resolution: {integrity: sha512-VwRvtY8OJSsSii3Is+8iqf48eY2tc5bKEgCOCQ3JKWhlDtj+Z9toXEQzR2aEiCk64M9AnzKFhFjDS+l7GmWIGg==} + + '@zag-js/toast@1.26.3': + resolution: {integrity: sha512-JOLvSHXC4hKlzNb2dDU7tvXIY6U4M+z8ewnHSAOO8Sl8OKTE3pbRU3Q9A0B2qW/3qteQA/P7411e5WrWdxn+9Q==} + + '@zag-js/toggle-group@1.26.3': + resolution: {integrity: sha512-CL6oOih/7R8r2NAq7U9HuR5MYlDmAPmS2q9VZINb415bKYuFEJyGMClFB3B+NFaLy6KG/voYahOBJ1NRsgMnxQ==} + + '@zag-js/toggle@1.26.3': + resolution: {integrity: sha512-nxsVxkQCTzeOCJcOwqrsIccSf+jjAKmVrmFD0l5IjvZWrypukKPmUFd9BgM7QYTtd3STaQPMMjkYzfFQ/SljzA==} + + '@zag-js/tooltip@1.26.3': + resolution: {integrity: sha512-givMhlRGWt9PD9JMrA+GBceD2ViQT8MUgb5r/ovDdaahW8xlMkosWIBnjJBafilrg3tw2Oemw1gPwctcPjAlMQ==} + + '@zag-js/tour@1.26.3': + resolution: {integrity: sha512-2WqYTpCTo46LWsF/arI+kuCexDDbgyKwE0hYjsK5NKf1BFAsAWpwmZ1Ne1RGDYl52sXMGfGu7tCQhDzGTzWU9w==} + + '@zag-js/tree-view@1.26.3': + resolution: {integrity: sha512-3P376SKf/poaUUjeobm/qenxaO8ApB/P/rpplkUE3fZVhnwKJbzKoUeNZiTpVX36FaJBb3AwBavmyQxMuYoxiQ==} + + '@zag-js/types@1.26.3': + resolution: {integrity: sha512-fJf2CgNLQuaFCRZzwGP69vWdFPc1bd1sPngzrYxIfT9SpIRFcBUrBa3p8hXlXg3EScx4O8qC0PrMe9NasUXV1Q==} + + '@zag-js/utils@1.26.3': + resolution: {integrity: sha512-C5PlGTVfuMYc/GydvyIyxjSoHib9ZNcinLoucZaRjXF4l6ClDPIlujXc11//XZ0EajpxOKNhfjP9m9stj5Vk0A==} + + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansis@4.2.0: + resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} + engines: {node: '>=14'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + ast-types@0.16.1: + resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} + engines: {node: '>=4'} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.12.2: + resolution: {integrity: sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==} + + babel-dead-code-elimination@1.0.10: + resolution: {integrity: sha512-DV5bdJZTzZ0zn0DC24v3jD7Mnidh6xhKa4GfKCbq3sfW8kaWhDdZjP3i81geA8T33tdYqWKw4D3fVv0CwEgKVA==} + + babel-plugin-macros@3.1.0: + resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} + engines: {node: '>=10', npm: '>=6'} + + baseline-browser-mapping@2.8.22: + resolution: {integrity: sha512-/tk9kky/d8T8CTXIQYASLyhAxR5VwL3zct1oAoVTaOUHwrmsGnfbRwNdEq+vOl2BN8i3PcDdP0o4Q+jjKQoFbQ==} + hasBin: true + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.27.0: + resolution: {integrity: sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + + c12@2.0.1: + resolution: {integrity: sha512-Z4JgsKXHG37C6PYUtIxCfLJZvo6FyhHJoClwwb9ftUkLpPSkuYqn6Tr+vnaN8hymm0kIbcg6Ey3kv/Q71k5w/A==} + peerDependencies: + magicast: ^0.3.5 + peerDependenciesMeta: + magicast: + optional: true + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + caniuse-lite@1.0.30001752: + resolution: {integrity: sha512-vKUk7beoukxE47P5gcVNKkDRzXdVofotshHwfR9vmpeFKxmI5PBpgOMC18LUJUA/DvJ70Y7RveasIBraqsyO/g==} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + + citty@0.1.6: + resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@13.0.0: + resolution: {integrity: sha512-oPYleIY8wmTVzkvQq10AEok6YcTC4sRUBl8F9gVuwchGVUCTbl/vhLTaQqutuuySYOsu8YTgV+OxKc/8Yvx+mQ==} + engines: {node: '>=18'} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-es@2.0.0: + resolution: {integrity: sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg==} + + cosmiconfig@7.1.0: + resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} + engines: {node: '>=10'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + default-browser-id@5.0.0: + resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} + engines: {node: '>=18'} + + default-browser@5.2.1: + resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} + engines: {node: '>=18'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + diff@8.0.2: + resolution: {integrity: sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==} + engines: {node: '>=0.3.1'} + + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + + dotenv@17.2.3: + resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + electron-to-chromium@1.5.244: + resolution: {integrity: sha512-OszpBN7xZX4vWMPJwB9illkN/znA8M36GQqQxi6MNy9axWxhOfJyZZJtSLQCpEFLHP2xK33BiWx9aIuIEXVCcw==} + + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + esbuild@0.25.11: + resolution: {integrity: sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-root@1.1.0: + resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.4: + resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + engines: {node: '>= 6'} + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.13.0: + resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + + giget@1.2.5: + resolution: {integrity: sha512-r1ekGw/Bgpi3HLV3h1MRBIlSAdHoIMklpaQ3OQLFcRw9PwAj2rqigvIbg+dBUI51OxVI2jsEtDywDBjSiuf7Ug==} + hasBin: true + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + goober@2.1.18: + resolution: {integrity: sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw==} + peerDependencies: + csstype: ^3.0.10 + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + + isbot@5.1.31: + resolution: {integrity: sha512-DPgQshehErHAqSCKDb3rNW03pa2wS/v5evvUqtxt6TTnHRqAG8FdzcSSJs9656pK6Y+NT7K9R4acEYXLHYfpUQ==} + engines: {node: '>=18'} + + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + mlly@1.8.0: + resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + next-themes@0.4.6: + resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} + peerDependencies: + react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + nypm@0.5.4: + resolution: {integrity: sha512-X0SNNrZiGU8/e/zAB7sCTtdxWTMSIO73q+xuKgglm2Yvzwlo8UoC5FNySQFCvl84uPaeADkqHUZUkWy4aH4xOA==} + engines: {node: ^14.16.0 || >=16.10.0} + hasBin: true + + ohash@1.1.6: + resolution: {integrity: sha512-TBu7PtV8YkAZn0tSxobKY2n2aAQva936lhRrj6957aDaCf9IEtqsKbgMzXE/F/sjqYOwmrukeORHNLe5glk7Cg==} + + open@10.1.2: + resolution: {integrity: sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==} + engines: {node: '>=18'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + + perfect-freehand@1.2.2: + resolution: {integrity: sha512-eh31l019WICQ03pkF3FSzHxB8n07ItqIQ++G5UV8JX0zVOXzgTGCqnRR0jJ2h9U8/2uW4W4mtGJELt9kEV0CFQ==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + playwright-core@1.56.1: + resolution: {integrity: sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.56.1: + resolution: {integrity: sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==} + engines: {node: '>=18'} + hasBin: true + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + prettier@3.6.2: + resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + engines: {node: '>=14'} + hasBin: true + + proxy-compare@3.0.1: + resolution: {integrity: sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q==} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + proxy-memoize@3.0.1: + resolution: {integrity: sha512-VDdG/VYtOgdGkWJx7y0o7p+zArSf2383Isci8C+BP3YXgMYDoPd3cCBjw0JdWb6YBb9sFiOPbAADDVTPJnh+9g==} + + rc9@2.1.2: + resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} + + react-dom@19.2.0: + resolution: {integrity: sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==} + peerDependencies: + react: ^19.2.0 + + react-error-boundary@6.0.0: + resolution: {integrity: sha512-gdlJjD7NWr0IfkPlaREN2d9uUZUlksrfOx7SX62VRerwXbMY6ftGCIZua1VG1aXFNOimhISsTq+Owp725b9SiA==} + peerDependencies: + react: '>=16.13.1' + + react-hook-form@7.62.0: + resolution: {integrity: sha512-7KWFejc98xqG/F4bAxpL41NB3o1nnvQO1RWZT3TqRZYL8RryQETGfEdVnJN2fy1crCiBLLjkRBVK05j24FxJGA==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 + + react-icons@5.5.0: + resolution: {integrity: sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==} + peerDependencies: + react: '*' + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react@19.2.0: + resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==} + engines: {node: '>=0.10.0'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + recast@0.23.11: + resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} + engines: {node: '>= 4'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + + rollup@4.52.5: + resolution: {integrity: sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + seroval-plugins@1.3.3: + resolution: {integrity: sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + + seroval@1.3.2: + resolution: {integrity: sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==} + engines: {node: '>=10'} + + solid-js@1.9.10: + resolution: {integrity: sha512-Coz956cos/EPDlhs6+jsdTxKuJDPT7B5SVIWgABwROyxjY7Xbr8wkzD68Et+NxnV7DLJ3nJdAC2r9InuV/4Jew==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + stylis@4.2.0: + resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tiny-warning@1.0.3: + resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsx@4.20.6: + resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==} + engines: {node: '>=18.0.0'} + hasBin: true + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.6.1: + resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + unplugin@2.3.10: + resolution: {integrity: sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw==} + engines: {node: '>=18.12.0'} + + update-browserslist-db@1.1.4: + resolution: {integrity: sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uqr@0.1.2: + resolution: {integrity: sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==} + + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + vite@7.1.12: + resolution: {integrity: sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + + zod@4.1.12: + resolution: {integrity: sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==} + +snapshots: + + '@ark-ui/react@5.26.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@internationalized/date': 3.10.0 + '@zag-js/accordion': 1.26.3 + '@zag-js/anatomy': 1.26.3 + '@zag-js/angle-slider': 1.26.3 + '@zag-js/async-list': 1.26.3 + '@zag-js/auto-resize': 1.26.3 + '@zag-js/avatar': 1.26.3 + '@zag-js/bottom-sheet': 1.26.3 + '@zag-js/carousel': 1.26.3 + '@zag-js/checkbox': 1.26.3 + '@zag-js/clipboard': 1.26.3 + '@zag-js/collapsible': 1.26.3 + '@zag-js/collection': 1.26.3 + '@zag-js/color-picker': 1.26.3 + '@zag-js/color-utils': 1.26.3 + '@zag-js/combobox': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/date-picker': 1.26.3(@internationalized/date@3.10.0) + '@zag-js/date-utils': 1.26.3(@internationalized/date@3.10.0) + '@zag-js/dialog': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/editable': 1.26.3 + '@zag-js/file-upload': 1.26.3 + '@zag-js/file-utils': 1.26.3 + '@zag-js/floating-panel': 1.26.3 + '@zag-js/focus-trap': 1.26.3 + '@zag-js/highlight-word': 1.26.3 + '@zag-js/hover-card': 1.26.3 + '@zag-js/i18n-utils': 1.26.3 + '@zag-js/json-tree-utils': 1.26.3 + '@zag-js/listbox': 1.26.3 + '@zag-js/menu': 1.26.3 + '@zag-js/number-input': 1.26.3 + '@zag-js/pagination': 1.26.3 + '@zag-js/password-input': 1.26.3 + '@zag-js/pin-input': 1.26.3 + '@zag-js/popover': 1.26.3 + '@zag-js/presence': 1.26.3 + '@zag-js/progress': 1.26.3 + '@zag-js/qr-code': 1.26.3 + '@zag-js/radio-group': 1.26.3 + '@zag-js/rating-group': 1.26.3 + '@zag-js/react': 1.26.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@zag-js/scroll-area': 1.26.3 + '@zag-js/select': 1.26.3 + '@zag-js/signature-pad': 1.26.3 + '@zag-js/slider': 1.26.3 + '@zag-js/splitter': 1.26.3 + '@zag-js/steps': 1.26.3 + '@zag-js/switch': 1.26.3 + '@zag-js/tabs': 1.26.3 + '@zag-js/tags-input': 1.26.3 + '@zag-js/timer': 1.26.3 + '@zag-js/toast': 1.26.3 + '@zag-js/toggle': 1.26.3 + '@zag-js/toggle-group': 1.26.3 + '@zag-js/tooltip': 1.26.3 + '@zag-js/tour': 1.26.3 + '@zag-js/tree-view': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.28.5': {} + + '@babel/core@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.28.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.28.5 + + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.28.5 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.27.0 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.28.5 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-member-expression-to-functions@7.28.5': + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.28.5 + + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.28.4': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + + '@babel/parser@7.28.5': + dependencies: + '@babel/types': 7.28.5 + + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-typescript@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-typescript': 7.28.5(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/runtime@7.28.4': {} + + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + + '@babel/traverse@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.28.5': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@biomejs/biome@2.3.2': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 2.3.2 + '@biomejs/cli-darwin-x64': 2.3.2 + '@biomejs/cli-linux-arm64': 2.3.2 + '@biomejs/cli-linux-arm64-musl': 2.3.2 + '@biomejs/cli-linux-x64': 2.3.2 + '@biomejs/cli-linux-x64-musl': 2.3.2 + '@biomejs/cli-win32-arm64': 2.3.2 + '@biomejs/cli-win32-x64': 2.3.2 + + '@biomejs/cli-darwin-arm64@2.3.2': + optional: true + + '@biomejs/cli-darwin-x64@2.3.2': + optional: true + + '@biomejs/cli-linux-arm64-musl@2.3.2': + optional: true + + '@biomejs/cli-linux-arm64@2.3.2': + optional: true + + '@biomejs/cli-linux-x64-musl@2.3.2': + optional: true + + '@biomejs/cli-linux-x64@2.3.2': + optional: true + + '@biomejs/cli-win32-arm64@2.3.2': + optional: true + + '@biomejs/cli-win32-x64@2.3.2': + optional: true + + '@chakra-ui/react@3.28.0(@emotion/react@11.14.0(@types/react@19.2.2)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@ark-ui/react': 5.26.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@emotion/is-prop-valid': 1.4.0 + '@emotion/react': 11.14.0(@types/react@19.2.2)(react@19.2.0) + '@emotion/serialize': 1.3.3 + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.0) + '@emotion/utils': 1.4.2 + '@pandacss/is-valid-prop': 1.4.3 + csstype: 3.1.3 + fast-safe-stringify: 2.1.1 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + + '@emotion/babel-plugin@11.13.5': + dependencies: + '@babel/helper-module-imports': 7.27.1 + '@babel/runtime': 7.28.4 + '@emotion/hash': 0.9.2 + '@emotion/memoize': 0.9.0 + '@emotion/serialize': 1.3.3 + babel-plugin-macros: 3.1.0 + convert-source-map: 1.9.0 + escape-string-regexp: 4.0.0 + find-root: 1.1.0 + source-map: 0.5.7 + stylis: 4.2.0 + transitivePeerDependencies: + - supports-color + + '@emotion/cache@11.14.0': + dependencies: + '@emotion/memoize': 0.9.0 + '@emotion/sheet': 1.4.0 + '@emotion/utils': 1.4.2 + '@emotion/weak-memoize': 0.4.0 + stylis: 4.2.0 + + '@emotion/hash@0.9.2': {} + + '@emotion/is-prop-valid@1.4.0': + dependencies: + '@emotion/memoize': 0.9.0 + + '@emotion/memoize@0.9.0': {} + + '@emotion/react@11.14.0(@types/react@19.2.2)(react@19.2.0)': + dependencies: + '@babel/runtime': 7.28.4 + '@emotion/babel-plugin': 11.13.5 + '@emotion/cache': 11.14.0 + '@emotion/serialize': 1.3.3 + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.0) + '@emotion/utils': 1.4.2 + '@emotion/weak-memoize': 0.4.0 + hoist-non-react-statics: 3.3.2 + react: 19.2.0 + optionalDependencies: + '@types/react': 19.2.2 + transitivePeerDependencies: + - supports-color + + '@emotion/serialize@1.3.3': + dependencies: + '@emotion/hash': 0.9.2 + '@emotion/memoize': 0.9.0 + '@emotion/unitless': 0.10.0 + '@emotion/utils': 1.4.2 + csstype: 3.1.3 + + '@emotion/sheet@1.4.0': {} + + '@emotion/unitless@0.10.0': {} + + '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.2.0)': + dependencies: + react: 19.2.0 + + '@emotion/utils@1.4.2': {} + + '@emotion/weak-memoize@0.4.0': {} + + '@esbuild/aix-ppc64@0.25.11': + optional: true + + '@esbuild/android-arm64@0.25.11': + optional: true + + '@esbuild/android-arm@0.25.11': + optional: true + + '@esbuild/android-x64@0.25.11': + optional: true + + '@esbuild/darwin-arm64@0.25.11': + optional: true + + '@esbuild/darwin-x64@0.25.11': + optional: true + + '@esbuild/freebsd-arm64@0.25.11': + optional: true + + '@esbuild/freebsd-x64@0.25.11': + optional: true + + '@esbuild/linux-arm64@0.25.11': + optional: true + + '@esbuild/linux-arm@0.25.11': + optional: true + + '@esbuild/linux-ia32@0.25.11': + optional: true + + '@esbuild/linux-loong64@0.25.11': + optional: true + + '@esbuild/linux-mips64el@0.25.11': + optional: true + + '@esbuild/linux-ppc64@0.25.11': + optional: true + + '@esbuild/linux-riscv64@0.25.11': + optional: true + + '@esbuild/linux-s390x@0.25.11': + optional: true + + '@esbuild/linux-x64@0.25.11': + optional: true + + '@esbuild/netbsd-arm64@0.25.11': + optional: true + + '@esbuild/netbsd-x64@0.25.11': + optional: true + + '@esbuild/openbsd-arm64@0.25.11': + optional: true + + '@esbuild/openbsd-x64@0.25.11': + optional: true + + '@esbuild/openharmony-arm64@0.25.11': + optional: true + + '@esbuild/sunos-x64@0.25.11': + optional: true + + '@esbuild/win32-arm64@0.25.11': + optional: true + + '@esbuild/win32-ia32@0.25.11': + optional: true + + '@esbuild/win32-x64@0.25.11': + optional: true + + '@floating-ui/core@1.7.3': + dependencies: + '@floating-ui/utils': 0.2.10 + + '@floating-ui/dom@1.7.4': + dependencies: + '@floating-ui/core': 1.7.3 + '@floating-ui/utils': 0.2.10 + + '@floating-ui/utils@0.2.10': {} + + '@hey-api/json-schema-ref-parser@1.0.6': + dependencies: + '@jsdevtools/ono': 7.1.3 + '@types/json-schema': 7.0.15 + js-yaml: 4.1.0 + lodash: 4.17.21 + + '@hey-api/openapi-ts@0.73.0(typescript@5.9.3)': + dependencies: + '@hey-api/json-schema-ref-parser': 1.0.6 + ansi-colors: 4.1.3 + c12: 2.0.1 + color-support: 1.1.3 + commander: 13.0.0 + handlebars: 4.7.8 + open: 10.1.2 + typescript: 5.9.3 + transitivePeerDependencies: + - magicast + + '@internationalized/date@3.10.0': + dependencies: + '@swc/helpers': 0.5.17 + + '@internationalized/number@3.6.5': + dependencies: + '@swc/helpers': 0.5.17 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@jsdevtools/ono@7.1.3': {} + + '@pandacss/is-valid-prop@1.4.3': {} + + '@playwright/test@1.56.1': + dependencies: + playwright: 1.56.1 + + '@rolldown/pluginutils@1.0.0-beta.43': {} + + '@rollup/rollup-android-arm-eabi@4.52.5': + optional: true + + '@rollup/rollup-android-arm64@4.52.5': + optional: true + + '@rollup/rollup-darwin-arm64@4.52.5': + optional: true + + '@rollup/rollup-darwin-x64@4.52.5': + optional: true + + '@rollup/rollup-freebsd-arm64@4.52.5': + optional: true + + '@rollup/rollup-freebsd-x64@4.52.5': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.52.5': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.52.5': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.52.5': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.52.5': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.52.5': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.52.5': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.52.5': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.52.5': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.52.5': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.52.5': + optional: true + + '@rollup/rollup-linux-x64-musl@4.52.5': + optional: true + + '@rollup/rollup-openharmony-arm64@4.52.5': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.52.5': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.52.5': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.52.5': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.52.5': + optional: true + + '@swc/core-darwin-arm64@1.14.0': + optional: true + + '@swc/core-darwin-x64@1.14.0': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.14.0': + optional: true + + '@swc/core-linux-arm64-gnu@1.14.0': + optional: true + + '@swc/core-linux-arm64-musl@1.14.0': + optional: true + + '@swc/core-linux-x64-gnu@1.14.0': + optional: true + + '@swc/core-linux-x64-musl@1.14.0': + optional: true + + '@swc/core-win32-arm64-msvc@1.14.0': + optional: true + + '@swc/core-win32-ia32-msvc@1.14.0': + optional: true + + '@swc/core-win32-x64-msvc@1.14.0': + optional: true + + '@swc/core@1.14.0(@swc/helpers@0.5.17)': + dependencies: + '@swc/counter': 0.1.3 + '@swc/types': 0.1.25 + optionalDependencies: + '@swc/core-darwin-arm64': 1.14.0 + '@swc/core-darwin-x64': 1.14.0 + '@swc/core-linux-arm-gnueabihf': 1.14.0 + '@swc/core-linux-arm64-gnu': 1.14.0 + '@swc/core-linux-arm64-musl': 1.14.0 + '@swc/core-linux-x64-gnu': 1.14.0 + '@swc/core-linux-x64-musl': 1.14.0 + '@swc/core-win32-arm64-msvc': 1.14.0 + '@swc/core-win32-ia32-msvc': 1.14.0 + '@swc/core-win32-x64-msvc': 1.14.0 + '@swc/helpers': 0.5.17 + + '@swc/counter@0.1.3': {} + + '@swc/helpers@0.5.17': + dependencies: + tslib: 2.8.1 + + '@swc/types@0.1.25': + dependencies: + '@swc/counter': 0.1.3 + + '@tanstack/history@1.133.28': {} + + '@tanstack/query-core@5.90.5': {} + + '@tanstack/query-devtools@5.90.1': {} + + '@tanstack/react-query-devtools@5.90.2(@tanstack/react-query@5.90.5(react@19.2.0))(react@19.2.0)': + dependencies: + '@tanstack/query-devtools': 5.90.1 + '@tanstack/react-query': 5.90.5(react@19.2.0) + react: 19.2.0 + + '@tanstack/react-query@5.90.5(react@19.2.0)': + dependencies: + '@tanstack/query-core': 5.90.5 + react: 19.2.0 + + '@tanstack/react-router-devtools@1.134.4(@tanstack/react-router@1.134.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@tanstack/router-core@1.134.4)(@types/node@24.9.2)(csstype@3.1.3)(jiti@2.6.1)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(solid-js@1.9.10)(tiny-invariant@1.3.3)(tsx@4.20.6)': + dependencies: + '@tanstack/react-router': 1.134.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@tanstack/router-devtools-core': 1.134.4(@tanstack/router-core@1.134.4)(@types/node@24.9.2)(csstype@3.1.3)(jiti@2.6.1)(solid-js@1.9.10)(tiny-invariant@1.3.3)(tsx@4.20.6) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(tsx@4.20.6) + transitivePeerDependencies: + - '@tanstack/router-core' + - '@types/node' + - csstype + - jiti + - less + - lightningcss + - sass + - sass-embedded + - solid-js + - stylus + - sugarss + - terser + - tiny-invariant + - tsx + - yaml + + '@tanstack/react-router@1.134.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@tanstack/history': 1.133.28 + '@tanstack/react-store': 0.8.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@tanstack/router-core': 1.134.4 + isbot: 5.1.31 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 + + '@tanstack/react-store@0.8.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@tanstack/store': 0.8.0 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + use-sync-external-store: 1.6.0(react@19.2.0) + + '@tanstack/router-core@1.134.4': + dependencies: + '@tanstack/history': 1.133.28 + '@tanstack/store': 0.8.0 + cookie-es: 2.0.0 + seroval: 1.3.2 + seroval-plugins: 1.3.3(seroval@1.3.2) + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 + + '@tanstack/router-devtools-core@1.134.4(@tanstack/router-core@1.134.4)(@types/node@24.9.2)(csstype@3.1.3)(jiti@2.6.1)(solid-js@1.9.10)(tiny-invariant@1.3.3)(tsx@4.20.6)': + dependencies: + '@tanstack/router-core': 1.134.4 + clsx: 2.1.1 + goober: 2.1.18(csstype@3.1.3) + solid-js: 1.9.10 + tiny-invariant: 1.3.3 + vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(tsx@4.20.6) + optionalDependencies: + csstype: 3.1.3 + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + + '@tanstack/router-devtools@1.134.4(@tanstack/react-router@1.134.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@tanstack/router-core@1.134.4)(@types/node@24.9.2)(csstype@3.1.3)(jiti@2.6.1)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(solid-js@1.9.10)(tiny-invariant@1.3.3)(tsx@4.20.6)': + dependencies: + '@tanstack/react-router': 1.134.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@tanstack/react-router-devtools': 1.134.4(@tanstack/react-router@1.134.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@tanstack/router-core@1.134.4)(@types/node@24.9.2)(csstype@3.1.3)(jiti@2.6.1)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(solid-js@1.9.10)(tiny-invariant@1.3.3)(tsx@4.20.6) + clsx: 2.1.1 + goober: 2.1.18(csstype@3.1.3) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(tsx@4.20.6) + optionalDependencies: + csstype: 3.1.3 + transitivePeerDependencies: + - '@tanstack/router-core' + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - solid-js + - stylus + - sugarss + - terser + - tiny-invariant + - tsx + - yaml + + '@tanstack/router-generator@1.134.4': + dependencies: + '@tanstack/router-core': 1.134.4 + '@tanstack/router-utils': 1.133.19 + '@tanstack/virtual-file-routes': 1.133.19 + prettier: 3.6.2 + recast: 0.23.11 + source-map: 0.7.6 + tsx: 4.20.6 + zod: 3.25.76 + transitivePeerDependencies: + - supports-color + + '@tanstack/router-plugin@1.134.6(@tanstack/react-router@1.134.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(tsx@4.20.6))': + dependencies: + '@babel/core': 7.28.5 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5) + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + '@tanstack/router-core': 1.134.4 + '@tanstack/router-generator': 1.134.4 + '@tanstack/router-utils': 1.133.19 + '@tanstack/virtual-file-routes': 1.133.19 + babel-dead-code-elimination: 1.0.10 + chokidar: 3.6.0 + unplugin: 2.3.10 + zod: 3.25.76 + optionalDependencies: + '@tanstack/react-router': 1.134.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(tsx@4.20.6) + transitivePeerDependencies: + - supports-color + + '@tanstack/router-utils@1.133.19': + dependencies: + '@babel/core': 7.28.5 + '@babel/generator': 7.28.5 + '@babel/parser': 7.28.5 + '@babel/preset-typescript': 7.28.5(@babel/core@7.28.5) + ansis: 4.2.0 + diff: 8.0.2 + pathe: 2.0.3 + tinyglobby: 0.2.15 + transitivePeerDependencies: + - supports-color + + '@tanstack/store@0.8.0': {} + + '@tanstack/virtual-file-routes@1.133.19': {} + + '@types/estree@1.0.8': {} + + '@types/json-schema@7.0.15': {} + + '@types/node@24.9.2': + dependencies: + undici-types: 7.16.0 + + '@types/parse-json@4.0.2': {} + + '@types/react-dom@19.2.2(@types/react@19.2.2)': + dependencies: + '@types/react': 19.2.2 + + '@types/react@19.2.2': + dependencies: + csstype: 3.1.3 + + '@vitejs/plugin-react-swc@4.2.0(@swc/helpers@0.5.17)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(tsx@4.20.6))': + dependencies: + '@rolldown/pluginutils': 1.0.0-beta.43 + '@swc/core': 1.14.0(@swc/helpers@0.5.17) + vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(tsx@4.20.6) + transitivePeerDependencies: + - '@swc/helpers' + + '@zag-js/accordion@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/anatomy@1.26.3': {} + + '@zag-js/angle-slider@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/rect-utils': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/aria-hidden@1.26.3': + dependencies: + '@zag-js/dom-query': 1.26.3 + + '@zag-js/async-list@1.26.3': + dependencies: + '@zag-js/core': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/auto-resize@1.26.3': + dependencies: + '@zag-js/dom-query': 1.26.3 + + '@zag-js/avatar@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/bottom-sheet@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/aria-hidden': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dismissable': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/focus-trap': 1.26.3 + '@zag-js/remove-scroll': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/carousel@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/scroll-snap': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/checkbox@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/focus-visible': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/clipboard@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/collapsible@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/collection@1.26.3': + dependencies: + '@zag-js/utils': 1.26.3 + + '@zag-js/color-picker@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/color-utils': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dismissable': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/popper': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/color-utils@1.26.3': + dependencies: + '@zag-js/utils': 1.26.3 + + '@zag-js/combobox@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/aria-hidden': 1.26.3 + '@zag-js/collection': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dismissable': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/popper': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/core@1.26.3': + dependencies: + '@zag-js/dom-query': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/date-picker@1.26.3(@internationalized/date@3.10.0)': + dependencies: + '@internationalized/date': 3.10.0 + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/date-utils': 1.26.3(@internationalized/date@3.10.0) + '@zag-js/dismissable': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/live-region': 1.26.3 + '@zag-js/popper': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/date-utils@1.26.3(@internationalized/date@3.10.0)': + dependencies: + '@internationalized/date': 3.10.0 + + '@zag-js/dialog@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/aria-hidden': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dismissable': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/focus-trap': 1.26.3 + '@zag-js/remove-scroll': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/dismissable@1.26.3': + dependencies: + '@zag-js/dom-query': 1.26.3 + '@zag-js/interact-outside': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/dom-query@1.26.3': + dependencies: + '@zag-js/types': 1.26.3 + + '@zag-js/editable@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/interact-outside': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/file-upload@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/file-utils': 1.26.3 + '@zag-js/i18n-utils': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/file-utils@1.26.3': + dependencies: + '@zag-js/i18n-utils': 1.26.3 + + '@zag-js/floating-panel@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/popper': 1.26.3 + '@zag-js/rect-utils': 1.26.3 + '@zag-js/store': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/focus-trap@1.26.3': + dependencies: + '@zag-js/dom-query': 1.26.3 + + '@zag-js/focus-visible@1.26.3': + dependencies: + '@zag-js/dom-query': 1.26.3 + + '@zag-js/highlight-word@1.26.3': {} + + '@zag-js/hover-card@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dismissable': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/popper': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/i18n-utils@1.26.3': + dependencies: + '@zag-js/dom-query': 1.26.3 + + '@zag-js/interact-outside@1.26.3': + dependencies: + '@zag-js/dom-query': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/json-tree-utils@1.26.3': {} + + '@zag-js/listbox@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/collection': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/focus-visible': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/live-region@1.26.3': {} + + '@zag-js/menu@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dismissable': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/popper': 1.26.3 + '@zag-js/rect-utils': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/number-input@1.26.3': + dependencies: + '@internationalized/number': 3.6.5 + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/pagination@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/password-input@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/pin-input@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/popover@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/aria-hidden': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dismissable': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/focus-trap': 1.26.3 + '@zag-js/popper': 1.26.3 + '@zag-js/remove-scroll': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/popper@1.26.3': + dependencies: + '@floating-ui/dom': 1.7.4 + '@zag-js/dom-query': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/presence@1.26.3': + dependencies: + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + + '@zag-js/progress@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/qr-code@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + proxy-memoize: 3.0.1 + uqr: 0.1.2 + + '@zag-js/radio-group@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/focus-visible': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/rating-group@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/react@1.26.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@zag-js/core': 1.26.3 + '@zag-js/store': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + + '@zag-js/rect-utils@1.26.3': {} + + '@zag-js/remove-scroll@1.26.3': + dependencies: + '@zag-js/dom-query': 1.26.3 + + '@zag-js/scroll-area@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/scroll-snap@1.26.3': + dependencies: + '@zag-js/dom-query': 1.26.3 + + '@zag-js/select@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/collection': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dismissable': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/popper': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/signature-pad@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + perfect-freehand: 1.2.2 + + '@zag-js/slider@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/splitter@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/steps@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/store@1.26.3': + dependencies: + proxy-compare: 3.0.1 + + '@zag-js/switch@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/focus-visible': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/tabs@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/tags-input@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/auto-resize': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/interact-outside': 1.26.3 + '@zag-js/live-region': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/timer@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/toast@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dismissable': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/toggle-group@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/toggle@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/tooltip@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/focus-visible': 1.26.3 + '@zag-js/popper': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/tour@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dismissable': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/focus-trap': 1.26.3 + '@zag-js/interact-outside': 1.26.3 + '@zag-js/popper': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/tree-view@1.26.3': + dependencies: + '@zag-js/anatomy': 1.26.3 + '@zag-js/collection': 1.26.3 + '@zag-js/core': 1.26.3 + '@zag-js/dom-query': 1.26.3 + '@zag-js/types': 1.26.3 + '@zag-js/utils': 1.26.3 + + '@zag-js/types@1.26.3': + dependencies: + csstype: 3.1.3 + + '@zag-js/utils@1.26.3': {} + + acorn@8.15.0: {} + + ansi-colors@4.1.3: {} + + ansis@4.2.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + argparse@2.0.1: {} + + ast-types@0.16.1: + dependencies: + tslib: 2.8.1 + + asynckit@0.4.0: {} + + axios@1.12.2: + dependencies: + follow-redirects: 1.15.11 + form-data: 4.0.4 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + babel-dead-code-elimination@1.0.10: + dependencies: + '@babel/core': 7.28.5 + '@babel/parser': 7.28.5 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + babel-plugin-macros@3.1.0: + dependencies: + '@babel/runtime': 7.28.4 + cosmiconfig: 7.1.0 + resolve: 1.22.11 + + baseline-browser-mapping@2.8.22: {} + + binary-extensions@2.3.0: {} + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.27.0: + dependencies: + baseline-browser-mapping: 2.8.22 + caniuse-lite: 1.0.30001752 + electron-to-chromium: 1.5.244 + node-releases: 2.0.27 + update-browserslist-db: 1.1.4(browserslist@4.27.0) + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.1.0 + + c12@2.0.1: + dependencies: + chokidar: 4.0.3 + confbox: 0.1.8 + defu: 6.1.4 + dotenv: 16.6.1 + giget: 1.2.5 + jiti: 2.6.1 + mlly: 1.8.0 + ohash: 1.1.6 + pathe: 1.1.2 + perfect-debounce: 1.0.0 + pkg-types: 1.3.1 + rc9: 2.1.2 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + callsites@3.1.0: {} + + caniuse-lite@1.0.30001752: {} + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + chownr@2.0.0: {} + + citty@0.1.6: + dependencies: + consola: 3.4.2 + + clsx@2.1.1: {} + + color-support@1.1.3: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@13.0.0: {} + + confbox@0.1.8: {} + + consola@3.4.2: {} + + convert-source-map@1.9.0: {} + + convert-source-map@2.0.0: {} + + cookie-es@2.0.0: {} + + cosmiconfig@7.1.0: + dependencies: + '@types/parse-json': 4.0.2 + import-fresh: 3.3.1 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + + csstype@3.1.3: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + default-browser-id@5.0.0: {} + + default-browser@5.2.1: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.0 + + define-lazy-prop@3.0.0: {} + + defu@6.1.4: {} + + delayed-stream@1.0.0: {} + + destr@2.0.5: {} + + diff@8.0.2: {} + + dotenv@16.6.1: {} + + dotenv@17.2.3: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + electron-to-chromium@1.5.244: {} + + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + esbuild@0.25.11: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.11 + '@esbuild/android-arm': 0.25.11 + '@esbuild/android-arm64': 0.25.11 + '@esbuild/android-x64': 0.25.11 + '@esbuild/darwin-arm64': 0.25.11 + '@esbuild/darwin-x64': 0.25.11 + '@esbuild/freebsd-arm64': 0.25.11 + '@esbuild/freebsd-x64': 0.25.11 + '@esbuild/linux-arm': 0.25.11 + '@esbuild/linux-arm64': 0.25.11 + '@esbuild/linux-ia32': 0.25.11 + '@esbuild/linux-loong64': 0.25.11 + '@esbuild/linux-mips64el': 0.25.11 + '@esbuild/linux-ppc64': 0.25.11 + '@esbuild/linux-riscv64': 0.25.11 + '@esbuild/linux-s390x': 0.25.11 + '@esbuild/linux-x64': 0.25.11 + '@esbuild/netbsd-arm64': 0.25.11 + '@esbuild/netbsd-x64': 0.25.11 + '@esbuild/openbsd-arm64': 0.25.11 + '@esbuild/openbsd-x64': 0.25.11 + '@esbuild/openharmony-arm64': 0.25.11 + '@esbuild/sunos-x64': 0.25.11 + '@esbuild/win32-arm64': 0.25.11 + '@esbuild/win32-ia32': 0.25.11 + '@esbuild/win32-x64': 0.25.11 + + escalade@3.2.0: {} + + escape-string-regexp@4.0.0: {} + + esprima@4.0.1: {} + + fast-safe-stringify@2.1.1: {} + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-root@1.1.0: {} + + follow-redirects@1.15.11: {} + + 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.35 + + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + fsevents@2.3.2: + optional: true + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gensync@1.0.0-beta.2: {} + + 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 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-tsconfig@4.13.0: + dependencies: + resolve-pkg-maps: 1.0.0 + + giget@1.2.5: + dependencies: + citty: 0.1.6 + consola: 3.4.2 + defu: 6.1.4 + node-fetch-native: 1.6.7 + nypm: 0.5.4 + pathe: 2.0.3 + tar: 6.2.1 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + goober@2.1.18(csstype@3.1.3): + dependencies: + csstype: 3.1.3 + + gopd@1.2.0: {} + + handlebars@4.7.8: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.19.3 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + is-arrayish@0.2.1: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-docker@3.0.0: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-number@7.0.0: {} + + is-wsl@3.1.0: + dependencies: + is-inside-container: 1.0.0 + + isbot@5.1.31: {} + + jiti@2.6.1: {} + + js-tokens@4.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-parse-even-better-errors@2.3.1: {} + + json5@2.2.3: {} + + lines-and-columns@1.2.4: {} + + lodash@4.17.21: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + math-intrinsics@1.1.0: {} + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + minimist@1.2.8: {} + + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@5.0.0: {} + + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + + mkdirp@1.0.4: {} + + mlly@1.8.0: + dependencies: + acorn: 8.15.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.1 + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + neo-async@2.6.2: {} + + next-themes@0.4.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + dependencies: + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + + node-fetch-native@1.6.7: {} + + node-releases@2.0.27: {} + + normalize-path@3.0.0: {} + + nypm@0.5.4: + dependencies: + citty: 0.1.6 + consola: 3.4.2 + pathe: 2.0.3 + pkg-types: 1.3.1 + tinyexec: 0.3.2 + ufo: 1.6.1 + + ohash@1.1.6: {} + + open@10.1.2: + dependencies: + default-browser: 5.2.1 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + is-wsl: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.27.1 + error-ex: 1.3.4 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + path-parse@1.0.7: {} + + path-type@4.0.0: {} + + pathe@1.1.2: {} + + pathe@2.0.3: {} + + perfect-debounce@1.0.0: {} + + perfect-freehand@1.2.2: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.3: {} + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.0 + pathe: 2.0.3 + + playwright-core@1.56.1: {} + + playwright@1.56.1: + dependencies: + playwright-core: 1.56.1 + optionalDependencies: + fsevents: 2.3.2 + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prettier@3.6.2: {} + + proxy-compare@3.0.1: {} + + proxy-from-env@1.1.0: {} + + proxy-memoize@3.0.1: + dependencies: + proxy-compare: 3.0.1 + + rc9@2.1.2: + dependencies: + defu: 6.1.4 + destr: 2.0.5 + + react-dom@19.2.0(react@19.2.0): + dependencies: + react: 19.2.0 + scheduler: 0.27.0 + + react-error-boundary@6.0.0(react@19.2.0): + dependencies: + '@babel/runtime': 7.28.4 + react: 19.2.0 + + react-hook-form@7.62.0(react@19.2.0): + dependencies: + react: 19.2.0 + + react-icons@5.5.0(react@19.2.0): + dependencies: + react: 19.2.0 + + react-is@16.13.1: {} + + react@19.2.0: {} + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + readdirp@4.1.2: {} + + recast@0.23.11: + dependencies: + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.8.1 + + resolve-from@4.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + rollup@4.52.5: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.52.5 + '@rollup/rollup-android-arm64': 4.52.5 + '@rollup/rollup-darwin-arm64': 4.52.5 + '@rollup/rollup-darwin-x64': 4.52.5 + '@rollup/rollup-freebsd-arm64': 4.52.5 + '@rollup/rollup-freebsd-x64': 4.52.5 + '@rollup/rollup-linux-arm-gnueabihf': 4.52.5 + '@rollup/rollup-linux-arm-musleabihf': 4.52.5 + '@rollup/rollup-linux-arm64-gnu': 4.52.5 + '@rollup/rollup-linux-arm64-musl': 4.52.5 + '@rollup/rollup-linux-loong64-gnu': 4.52.5 + '@rollup/rollup-linux-ppc64-gnu': 4.52.5 + '@rollup/rollup-linux-riscv64-gnu': 4.52.5 + '@rollup/rollup-linux-riscv64-musl': 4.52.5 + '@rollup/rollup-linux-s390x-gnu': 4.52.5 + '@rollup/rollup-linux-x64-gnu': 4.52.5 + '@rollup/rollup-linux-x64-musl': 4.52.5 + '@rollup/rollup-openharmony-arm64': 4.52.5 + '@rollup/rollup-win32-arm64-msvc': 4.52.5 + '@rollup/rollup-win32-ia32-msvc': 4.52.5 + '@rollup/rollup-win32-x64-gnu': 4.52.5 + '@rollup/rollup-win32-x64-msvc': 4.52.5 + fsevents: 2.3.3 + + run-applescript@7.1.0: {} + + scheduler@0.27.0: {} + + semver@6.3.1: {} + + seroval-plugins@1.3.3(seroval@1.3.2): + dependencies: + seroval: 1.3.2 + + seroval@1.3.2: {} + + solid-js@1.9.10: + dependencies: + csstype: 3.1.3 + seroval: 1.3.2 + seroval-plugins: 1.3.3(seroval@1.3.2) + + source-map-js@1.2.1: {} + + source-map@0.5.7: {} + + source-map@0.6.1: {} + + source-map@0.7.6: {} + + stylis@4.2.0: {} + + supports-preserve-symlinks-flag@1.0.0: {} + + tar@6.2.1: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + + tiny-invariant@1.3.3: {} + + tiny-warning@1.0.3: {} + + tinyexec@0.3.2: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tslib@2.8.1: {} + + tsx@4.20.6: + dependencies: + esbuild: 0.25.11 + get-tsconfig: 4.13.0 + optionalDependencies: + fsevents: 2.3.3 + + typescript@5.9.3: {} + + ufo@1.6.1: {} + + uglify-js@3.19.3: + optional: true + + undici-types@7.16.0: {} + + unplugin@2.3.10: + dependencies: + '@jridgewell/remapping': 2.3.5 + acorn: 8.15.0 + picomatch: 4.0.3 + webpack-virtual-modules: 0.6.2 + + update-browserslist-db@1.1.4(browserslist@4.27.0): + dependencies: + browserslist: 4.27.0 + escalade: 3.2.0 + picocolors: 1.1.1 + + uqr@0.1.2: {} + + use-sync-external-store@1.6.0(react@19.2.0): + dependencies: + react: 19.2.0 + + vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(tsx@4.20.6): + dependencies: + esbuild: 0.25.11 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.52.5 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 24.9.2 + fsevents: 2.3.3 + jiti: 2.6.1 + tsx: 4.20.6 + + webpack-virtual-modules@0.6.2: {} + + wordwrap@1.0.0: {} + + yallist@3.1.1: {} + + yallist@4.0.0: {} + + yaml@1.10.2: {} + + zod@3.25.76: {} + + zod@4.1.12: {} diff --git a/frontend/src/components/Payments/Checkout.tsx b/frontend/src/components/Payments/Checkout.tsx new file mode 100644 index 0000000000..490ab86cf0 --- /dev/null +++ b/frontend/src/components/Payments/Checkout.tsx @@ -0,0 +1,289 @@ +import { + Box, + Button, + Container, + Heading, + Input, + SimpleGrid, + Text, + VStack, +} from "@chakra-ui/react" +import { useNavigate } from "@tanstack/react-router" +import { useState } from "react" +import { type SubmitHandler, useForm } from "react-hook-form" +import { useQuery, useQueryClient } from "@tanstack/react-query" + +import { PaymentsService } from "@/client" +import type { ApiError } from "@/client/core/ApiError" +import useCustomToast from "@/hooks/useCustomToast" +import { handleError } from "@/utils" +import { Field } from "../ui/field" +import { Table } from "@chakra-ui/react" + +const Checkout = () => { + const navigate = useNavigate() + const { showErrorToast } = useCustomToast() + const queryClient = useQueryClient() + const [isProcessing, setIsProcessing] = useState(false) + const { + register, + handleSubmit, + formState: { errors, isValid }, + } = useForm<{ amount: number; currency: string }>({ + mode: "onBlur", + defaultValues: { + amount: 1, // Default 1 INR + currency: "INR", + }, + }) + + // Fetch payment analytics + const { data: ordersData, isLoading } = useQuery({ + queryKey: ["orders"], + queryFn: () => PaymentsService.readOrders({}), + }) + + const onSubmit: SubmitHandler<{ amount: number; currency: string }> = async ( + data + ) => { + if (isProcessing) return + + setIsProcessing(true) + + try { + // Convert rupees to paise (multiply by 100) + const amountInPaise = Math.round(data.amount * 100) + + // Create order using generated client + const orderData = await PaymentsService.createOrder({ + requestBody: { + amount: amountInPaise, + currency: data.currency, + }, + }) + + // Open Razorpay Checkout + if (!(window as any).Razorpay) { + showErrorToast("Razorpay checkout is not loaded. Please refresh the page.") + setIsProcessing(false) + return + } + + const options = { + key: orderData.key, + amount: orderData.amount, + currency: orderData.currency, + name: "FastAPI Payment", + description: "Payment for order", + order_id: orderData.id, + handler: async (response: { + razorpay_payment_id: string + razorpay_order_id: string + razorpay_signature: string + }) => { + try { + // Verify payment on backend using generated client + await PaymentsService.verifyPayment({ + requestBody: { + razorpay_order_id: response.razorpay_order_id, + razorpay_payment_id: response.razorpay_payment_id, + razorpay_signature: response.razorpay_signature, + }, + }) + + // Invalidate orders query to refresh the list + queryClient.invalidateQueries({ queryKey: ["orders"] }) + + // Redirect to success page + navigate({ + to: "/payment-success", + search: { + order_id: response.razorpay_order_id, + payment_id: response.razorpay_payment_id, + }, + }) + } catch (error) { + handleError(error as ApiError) + navigate({ + to: "/payment-failure", + search: { + error: "Payment verification failed", + }, + }) + } + }, + prefill: { + name: "", + email: "", + contact: "", + }, + theme: { + color: "#2563eb", // Blue theme color + }, + modal: { + ondismiss: () => { + setIsProcessing(false) + }, + }, + } + + const rzp = new (window as any).Razorpay(options) + rzp.open() + } catch (error) { + handleError(error as ApiError) + setIsProcessing(false) + } + } + + const orders = ordersData?.data || [] + const totalAmount = orders.reduce( + (sum: number, order: { amount: string | number }) => sum + parseInt(String(order.amount)), + 0 + ) + const successfulPayments = orders.filter( + (order: { status: string }) => order.status === "paid" + ).length + const failedPayments = orders.filter( + (order: { status: string }) => order.status === "failed" + ).length + + return ( + + + {/* Payment Form Section */} + + Make a Payment + Enter the amount you want to pay +
+ + + + + + + + + + + +
+
+ + {/* Payment Analytics Dashboard Section */} + + Payment Dashboard + + {/* Statistics Cards */} + + + Total Spent + + ₹{(totalAmount / 100).toFixed(2)} + + + + Successful Payments + {successfulPayments} + + + Failed Payments + {failedPayments} + + + + {/* Recent Orders Table */} + + Recent Orders + {isLoading ? ( + Loading orders... + ) : ( + + + + Order ID + Amount + Status + Date + + + + {orders.slice(0, 10).map((order: any) => ( + + + + {order.razorpay_order_id} + + + ₹{(parseInt(String(order.amount)) / 100).toFixed(2)} + + + {order.status} + + + + {new Date(order.created_at).toLocaleDateString()} + + + ))} + {orders.length === 0 && ( + + + No orders found. Make your first payment above! + + + )} + + + )} + + +
+
+ ) +} + +export default Checkout + diff --git a/frontend/src/components/Payments/PaymentAnalytics.tsx b/frontend/src/components/Payments/PaymentAnalytics.tsx new file mode 100644 index 0000000000..5b93be7345 --- /dev/null +++ b/frontend/src/components/Payments/PaymentAnalytics.tsx @@ -0,0 +1,102 @@ +import { + Box, + Container, + Heading, + SimpleGrid, + Table, + Text, + VStack, +} from "@chakra-ui/react" +import { useQuery } from "@tanstack/react-query" + +import { PaymentsService } from "@/client" + +const PaymentAnalytics = () => { + const { data: ordersData, isLoading } = useQuery({ + queryKey: ["orders"], + queryFn: () => PaymentsService.readOrders({}), + }) + + if (isLoading) { + return Loading analytics... + } + + const orders = ordersData?.data || [] + const totalAmount = orders.reduce( + (sum: number, order: { amount: string | number }) => sum + parseInt(String(order.amount)), + 0 + ) + const successfulPayments = orders.filter( + (order: { status: string }) => order.status === "paid" + ).length + const failedPayments = orders.filter( + (order: { status: string }) => order.status === "failed" + ).length + + return ( + + + Payment Analytics + + + + Total Spent + ₹{(totalAmount / 100).toFixed(2)} + + + Successful Payments + {successfulPayments} + + + Failed Payments + {failedPayments} + + + + + + Recent Orders + + + + + Order ID + Amount + Status + Date + + + + {orders.slice(0, 10).map((order: any) => ( + + + + {order.razorpay_order_id} + + + ₹{(parseInt(String(order.amount)) / 100).toFixed(2)} + + {order.status} + + + {new Date(order.created_at).toLocaleDateString()} + + + ))} + {orders.length === 0 && ( + + + No orders found + + + )} + + + + + + ) +} + +export default PaymentAnalytics + diff --git a/frontend/src/components/Payments/PaymentFailure.tsx b/frontend/src/components/Payments/PaymentFailure.tsx new file mode 100644 index 0000000000..b2c0cd276f --- /dev/null +++ b/frontend/src/components/Payments/PaymentFailure.tsx @@ -0,0 +1,54 @@ +import { + Box, + Button, + Container, + Heading, + HStack, + Text, + VStack, +} from "@chakra-ui/react" +import { Link, useSearch } from "@tanstack/react-router" +import { FaExclamationTriangle } from "react-icons/fa" + +interface PaymentFailureSearch { + error?: string +} + +const PaymentFailure = () => { + const search = useSearch({ from: "/payment-failure" }) as PaymentFailureSearch + const { error } = search || {} + + return ( + + + + + + Payment Failed + + + {error || "Your payment could not be processed. Please try again."} + + + If you were charged, the amount will be refunded to your account within + 5-7 business days. + + + + + + + + + + + + + + ) +} + +export default PaymentFailure + diff --git a/frontend/src/components/Payments/PaymentSuccess.tsx b/frontend/src/components/Payments/PaymentSuccess.tsx new file mode 100644 index 0000000000..d3ac437cc9 --- /dev/null +++ b/frontend/src/components/Payments/PaymentSuccess.tsx @@ -0,0 +1,134 @@ +import { + Box, + Button, + Container, + Heading, + HStack, + SimpleGrid, + Text, + VStack, +} from "@chakra-ui/react" +import { Link, useSearch } from "@tanstack/react-router" +import { useQuery } from "@tanstack/react-query" +import { FaCheckCircle } from "react-icons/fa" + +import { PaymentsService } from "@/client" + +interface PaymentSuccessSearch { + order_id?: string + payment_id?: string +} + +const PaymentSuccess = () => { + const search = useSearch({ from: "/payment-success" }) as PaymentSuccessSearch + const { order_id, payment_id } = search || {} + + // Fetch order details for analytics + const { data: orderData, isLoading } = useQuery({ + queryKey: ["order", order_id], + queryFn: async () => { + if (!order_id) return null + const data = await PaymentsService.readOrders({}) + // Find the specific order + return data.data?.find( + (o: { razorpay_order_id: string }) => o.razorpay_order_id === order_id + ) + }, + enabled: !!order_id, + }) + + return ( + + + + + + + Payment Successful! + + + Your payment has been processed successfully. + + + + + + + Payment Details + + + {order_id && ( + + Order ID + + {order_id} + + + )} + {payment_id && ( + + Payment ID + + {payment_id} + + + )} + {orderData && ( + <> + + Amount + + ₹{(parseInt(String(orderData.amount)) / 100).toFixed(2)} + + + + Status + {orderData.status} + + + )} + + + + + + Database Updates Analytics + + + + ✅ Order record created in database with status: + {orderData?.status || "paid"} + + + ✅ Payment record added to database with payment ID: + {payment_id || "N/A"} + + + ✅ User payment history updated - This transaction has + been added to your order history + + {isLoading && Loading order details...} + {orderData && ( + + ✅ Order timestamp:{" "} + {new Date(orderData.created_at).toLocaleString()} + + )} + + + + + + + + + + + + + + ) +} + +export default PaymentSuccess + diff --git a/frontend/src/routes/_layout/checkout.tsx b/frontend/src/routes/_layout/checkout.tsx new file mode 100644 index 0000000000..4ad1a0e4fe --- /dev/null +++ b/frontend/src/routes/_layout/checkout.tsx @@ -0,0 +1,8 @@ +import { createFileRoute } from "@tanstack/react-router" + +import Checkout from "@/components/Payments/Checkout" + +export const Route = createFileRoute("/_layout/checkout")({ + component: Checkout, +}) + diff --git a/frontend/src/routes/payment-failure.tsx b/frontend/src/routes/payment-failure.tsx new file mode 100644 index 0000000000..0acb459d9f --- /dev/null +++ b/frontend/src/routes/payment-failure.tsx @@ -0,0 +1,13 @@ +import { createFileRoute } from "@tanstack/react-router" + +import PaymentFailure from "@/components/Payments/PaymentFailure" + +export const Route = createFileRoute("/payment-failure")({ + component: PaymentFailure, + validateSearch: (search: Record) => { + return { + error: (search.error as string) || undefined, + } + }, +}) + diff --git a/frontend/src/routes/payment-success.tsx b/frontend/src/routes/payment-success.tsx new file mode 100644 index 0000000000..1fd05c084d --- /dev/null +++ b/frontend/src/routes/payment-success.tsx @@ -0,0 +1,14 @@ +import { createFileRoute } from "@tanstack/react-router" + +import PaymentSuccess from "@/components/Payments/PaymentSuccess" + +export const Route = createFileRoute("/payment-success")({ + component: PaymentSuccess, + validateSearch: (search: Record) => { + return { + order_id: (search.order_id as string) || undefined, + payment_id: (search.payment_id as string) || undefined, + } + }, +}) + diff --git a/img/checkout.png b/img/checkout.png new file mode 100644 index 0000000000..05346521a6 Binary files /dev/null and b/img/checkout.png differ diff --git a/img/razorpay.png b/img/razorpay.png new file mode 100644 index 0000000000..84377cc41e Binary files /dev/null and b/img/razorpay.png differ