From af1e96f2ed41228a649eec253a07aea47b62bb79 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Mon, 15 Sep 2025 09:20:30 +0200 Subject: [PATCH 01/43] moving plugins to separate directory --- plugins/zammad/alembic.ini | 90 --- plugins/zammad/main.py | 719 ------------------ plugins/zammad/manifest.yaml | 253 ------ plugins/zammad/migrations/env.py | 85 --- plugins/zammad/migrations/script.py.mako | 24 - .../versions/001_initial_zammad_schema.py | 112 --- plugins/zammad/requirements.txt | 4 - .../zammad/ui/components/ZammadDashboard.tsx | 414 ---------- .../zammad/ui/components/ZammadSettings.tsx | 512 ------------- 9 files changed, 2213 deletions(-) delete mode 100644 plugins/zammad/alembic.ini delete mode 100644 plugins/zammad/main.py delete mode 100644 plugins/zammad/manifest.yaml delete mode 100644 plugins/zammad/migrations/env.py delete mode 100644 plugins/zammad/migrations/script.py.mako delete mode 100644 plugins/zammad/migrations/versions/001_initial_zammad_schema.py delete mode 100644 plugins/zammad/requirements.txt delete mode 100644 plugins/zammad/ui/components/ZammadDashboard.tsx delete mode 100644 plugins/zammad/ui/components/ZammadSettings.tsx diff --git a/plugins/zammad/alembic.ini b/plugins/zammad/alembic.ini deleted file mode 100644 index ad77bf5..0000000 --- a/plugins/zammad/alembic.ini +++ /dev/null @@ -1,90 +0,0 @@ -# A generic, single database configuration. - -[alembic] -# template used to generate migration file names; The default value is %%(rev)s_%%(slug)s -# Uncomment the line below if you want the files to be prepended with date and time -# file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s - -# path to migration scripts -script_location = migrations - -# template used to generate migration file names; The default value is %%(rev)s_%%(slug)s -# Uncomment the line below if you want the files to be prepended with date and time -# file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s - -# sys.path path, will be prepended to sys.path if present. -# defaults to the current working directory. -prepend_sys_path = . - -# timezone to use when rendering the date within the migration file -# as well as the filename. -# If specified, requires the python-dateutil library that can be installed by running "pip install alembic[tz]" -# timezone = - -# max length of characters to apply to the -# "slug" field -# truncate_slug_length = 40 - -# set to 'true' to run the environment during -# the 'revision' command, regardless of autogenerate -# revision_environment = false - -# set to 'true' to allow .pyc and .pyo files without -# a source .py file to be detected as revisions in the -# versions/ directory -# sourceless = false - -# version path separator; As mentioned above, this is the character used to split -# version_locations. The default within new alembic.ini files is "os", which uses -# os.pathsep. If this key is omitted entirely, it falls back to the legacy -# behavior of splitting on spaces and/or commas. -# Valid values for version_path_separator are: -# -# version_path_separator = : -# version_path_separator = ; -# version_path_separator = space -version_path_separator = os - -# set to 'true' to search source files recursively -# in each "version_locations" directory -# new in Alembic version 1.10 -# recursive_version_locations = false - -# the output encoding used when revision files -# are written from script.py.mako -# output_encoding = utf-8 - -# Logging configuration -[loggers] -keys = root,sqlalchemy,alembic - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = WARN -handlers = console -qualname = - -[logger_sqlalchemy] -level = WARN -handlers = -qualname = sqlalchemy.engine - -[logger_alembic] -level = INFO -handlers = -qualname = alembic - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(levelname)-5.5s [%(name)s] %(message)s -datefmt = %H:%M:%S \ No newline at end of file diff --git a/plugins/zammad/main.py b/plugins/zammad/main.py deleted file mode 100644 index e232e06..0000000 --- a/plugins/zammad/main.py +++ /dev/null @@ -1,719 +0,0 @@ -""" -Zammad Plugin Implementation -Provides integration between Enclava platform and Zammad helpdesk system -""" -from typing import Dict, Any, List, Optional -from fastapi import APIRouter, HTTPException, Depends, BackgroundTasks -from pydantic import BaseModel -import aiohttp -import asyncio -from datetime import datetime, timezone - -from app.services.base_plugin import BasePlugin, PluginContext -from app.services.plugin_database import PluginDatabaseSession, plugin_db_manager -from app.services.plugin_security import plugin_security_policy_manager -from sqlalchemy import Column, String, DateTime, Text, Boolean, Integer, ForeignKey -from sqlalchemy.ext.declarative import declarative_base -from sqlalchemy.orm import relationship -from sqlalchemy.dialects.postgresql import UUID -import uuid - - -class ZammadTicket(BaseModel): - """Zammad ticket model""" - id: str - title: str - body: str - status: str - priority: str - customer_id: str - group_id: str - created_at: datetime - updated_at: datetime - ai_summary: Optional[str] = None - - -class ZammadConfiguration(BaseModel): - """Zammad configuration model""" - name: str - zammad_url: str - api_token: str - chatbot_id: str - ai_summarization: Dict[str, Any] - sync_settings: Dict[str, Any] - webhook_settings: Dict[str, Any] - - -# Plugin database models -Base = declarative_base() - -class ZammadConfiguration(Base): - __tablename__ = "zammad_configurations" - - id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) - user_id = Column(String, nullable=False, index=True) - name = Column(String(100), nullable=False) - zammad_url = Column(String(500), nullable=False) - api_token_encrypted = Column(Text, nullable=False) - chatbot_id = Column(String(100), nullable=False) - is_active = Column(Boolean, default=True) - ai_summarization_enabled = Column(Boolean, default=True) - auto_summarize = Column(Boolean, default=True) - sync_enabled = Column(Boolean, default=True) - sync_interval_hours = Column(Integer, default=2) - created_at = Column(DateTime, default=datetime.now(timezone.utc)) - updated_at = Column(DateTime, default=datetime.now(timezone.utc), onupdate=datetime.now(timezone.utc)) - -class ZammadTicket(Base): - __tablename__ = "zammad_tickets" - - id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) - zammad_ticket_id = Column(String(50), nullable=False, index=True) - configuration_id = Column(UUID(as_uuid=True), ForeignKey("zammad_configurations.id")) - title = Column(String(500), nullable=False) - body = Column(Text) - status = Column(String(50)) - priority = Column(String(50)) - customer_id = Column(String(50)) - group_id = Column(String(50)) - ai_summary = Column(Text) - last_synced = Column(DateTime, default=datetime.now(timezone.utc)) - created_at = Column(DateTime, default=datetime.now(timezone.utc)) - updated_at = Column(DateTime, default=datetime.now(timezone.utc), onupdate=datetime.now(timezone.utc)) - - configuration = relationship("ZammadConfiguration", back_populates="tickets") - -ZammadConfiguration.tickets = relationship("ZammadTicket", back_populates="configuration") - -class ZammadPlugin(BasePlugin): - """Zammad helpdesk integration plugin with full framework integration""" - - def __init__(self, manifest, plugin_token: str): - super().__init__(manifest, plugin_token) - self.zammad_client = None - self.db_models = [ZammadConfiguration, ZammadTicket] - - async def initialize(self) -> bool: - """Initialize Zammad plugin with database setup""" - try: - self.logger.info("Initializing Zammad plugin") - - # Create database tables - await self._create_database_tables() - - # Test platform API connectivity - health = await self.api_client.get("/health") - self.logger.info(f"Platform API health: {health.get('status')}") - - # Validate security policy - policy = plugin_security_policy_manager.get_security_policy(self.plugin_id, None) - self.logger.info(f"Security policy loaded: {policy.get('max_api_calls_per_minute')} calls/min") - - self.logger.info("Zammad plugin initialized successfully") - return True - - except Exception as e: - self.logger.error(f"Failed to initialize Zammad plugin: {e}") - return False - - async def _create_database_tables(self): - """Create plugin database tables""" - try: - engine = await plugin_db_manager.get_plugin_engine(self.plugin_id) - if engine: - async with engine.begin() as conn: - await conn.run_sync(Base.metadata.create_all) - self.logger.info("Database tables created successfully") - except Exception as e: - self.logger.error(f"Failed to create database tables: {e}") - raise - - async def cleanup(self) -> bool: - """Cleanup plugin resources""" - try: - self.logger.info("Cleaning up Zammad plugin") - # Close any open connections - return True - except Exception as e: - self.logger.error(f"Error during cleanup: {e}") - return False - - def get_api_router(self) -> APIRouter: - """Return FastAPI router for Zammad endpoints""" - router = APIRouter() - - @router.get("/health") - async def health_check(): - """Plugin health check endpoint""" - return await self.health_check() - - @router.get("/tickets") - async def get_tickets(context: PluginContext = Depends(self.get_auth_context)): - """Get tickets from Zammad""" - try: - self._track_request() - - config = await self.get_active_config(context.user_id) - if not config: - raise HTTPException(status_code=404, detail="No Zammad configuration found") - - tickets = await self.fetch_tickets_from_zammad(config) - return {"tickets": tickets, "count": len(tickets)} - - except Exception as e: - self._track_request(success=False) - self.logger.error(f"Error fetching tickets: {e}") - raise HTTPException(status_code=500, detail=str(e)) - - @router.get("/tickets/{ticket_id}") - async def get_ticket(ticket_id: str, context: PluginContext = Depends(self.get_auth_context)): - """Get specific ticket from Zammad""" - try: - self._track_request() - - config = await self.get_active_config(context.user_id) - if not config: - raise HTTPException(status_code=404, detail="No Zammad configuration found") - - ticket = await self.fetch_ticket_from_zammad(config, ticket_id) - return {"ticket": ticket} - - except Exception as e: - self._track_request(success=False) - self.logger.error(f"Error fetching ticket {ticket_id}: {e}") - raise HTTPException(status_code=500, detail=str(e)) - - @router.post("/tickets/{ticket_id}/summarize") - async def summarize_ticket( - ticket_id: str, - background_tasks: BackgroundTasks, - context: PluginContext = Depends(self.get_auth_context) - ): - """Generate AI summary for ticket""" - try: - self._track_request() - - config = await self.get_active_config(context.user_id) - if not config: - raise HTTPException(status_code=404, detail="No Zammad configuration found") - - # Start summarization in background - background_tasks.add_task( - self.summarize_ticket_async, - config, - ticket_id, - context.user_id - ) - - return { - "status": "started", - "ticket_id": ticket_id, - "message": "AI summarization started in background" - } - - except Exception as e: - self._track_request(success=False) - self.logger.error(f"Error starting summarization for ticket {ticket_id}: {e}") - raise HTTPException(status_code=500, detail=str(e)) - - @router.post("/webhooks/ticket-created") - async def handle_ticket_webhook(webhook_data: Dict[str, Any]): - """Handle Zammad webhook for new tickets""" - try: - ticket_id = webhook_data.get("ticket", {}).get("id") - if not ticket_id: - raise HTTPException(status_code=400, detail="Invalid webhook data") - - self.logger.info(f"Received webhook for ticket: {ticket_id}") - - # Process webhook asynchronously - asyncio.create_task(self.process_ticket_webhook(webhook_data)) - - return {"status": "processed", "ticket_id": ticket_id} - - except Exception as e: - self.logger.error(f"Error processing webhook: {e}") - raise HTTPException(status_code=500, detail=str(e)) - - @router.get("/configurations") - async def get_configurations(context: PluginContext = Depends(self.get_auth_context)): - """Get user's Zammad configurations""" - try: - configs = await self.get_user_configurations(context.user_id) - return {"configurations": configs} - except Exception as e: - self.logger.error(f"Error fetching configurations: {e}") - raise HTTPException(status_code=500, detail=str(e)) - - @router.post("/configurations") - async def create_configuration( - config_data: Dict[str, Any], - context: PluginContext = Depends(self.get_auth_context) - ): - """Create new Zammad configuration""" - try: - # Validate configuration against schema - schema = await self.get_configuration_schema() - is_valid, errors = await self.config.validate_config(config_data, schema) - - if not is_valid: - raise HTTPException(status_code=400, detail=f"Invalid configuration: {errors}") - - # Test connection before saving - connection_test = await self.test_zammad_connection(config_data) - if not connection_test["success"]: - raise HTTPException( - status_code=400, - detail=f"Connection test failed: {connection_test['error']}" - ) - - # Save configuration to plugin database - success = await self._save_configuration_to_db(config_data, context.user_id) - if not success: - raise HTTPException(status_code=500, detail="Failed to save configuration") - - return {"status": "created", "config": {"name": config_data.get("name"), "zammad_url": config_data.get("zammad_url")}} - - except HTTPException: - raise - except Exception as e: - self.logger.error(f"Error creating configuration: {e}") - raise HTTPException(status_code=500, detail=str(e)) - - @router.get("/statistics") - async def get_statistics(context: PluginContext = Depends(self.get_auth_context)): - """Get plugin usage statistics""" - try: - stats = await self._get_plugin_statistics(context.user_id) - return stats - except Exception as e: - self.logger.error(f"Error getting statistics: {e}") - raise HTTPException(status_code=500, detail=str(e)) - - @router.get("/tickets/sync") - async def sync_tickets_manual(context: PluginContext = Depends(self.get_auth_context)): - """Manually trigger ticket sync""" - try: - result = await self._sync_user_tickets(context.user_id) - return {"status": "completed", "synced_count": result} - except Exception as e: - self.logger.error(f"Error syncing tickets: {e}") - raise HTTPException(status_code=500, detail=str(e)) - - return router - - # Plugin-specific methods - - async def get_active_config(self, user_id: str) -> Optional[Dict[str, Any]]: - """Get active Zammad configuration for user from database""" - try: - async with PluginDatabaseSession(self.plugin_id, plugin_db_manager) as db: - config = await db.query(ZammadConfiguration).filter( - ZammadConfiguration.user_id == user_id, - ZammadConfiguration.is_active == True - ).first() - - if config: - # Decrypt API token - from app.services.plugin_security import plugin_token_manager - api_token = plugin_token_manager.decrypt_plugin_secret(config.api_token_encrypted) - - return { - "id": str(config.id), - "name": config.name, - "zammad_url": config.zammad_url, - "api_token": api_token, - "chatbot_id": config.chatbot_id, - "ai_summarization": { - "enabled": config.ai_summarization_enabled, - "auto_summarize": config.auto_summarize - }, - "sync_settings": { - "enabled": config.sync_enabled, - "interval_hours": config.sync_interval_hours - } - } - return None - except Exception as e: - self.logger.error(f"Failed to get active config: {e}") - return None - - async def get_user_configurations(self, user_id: str) -> List[Dict[str, Any]]: - """Get all configurations for user from database""" - try: - async with PluginDatabaseSession(self.plugin_id, plugin_db_manager) as db: - configs = await db.query(ZammadConfiguration).filter( - ZammadConfiguration.user_id == user_id - ).all() - - result = [] - for config in configs: - result.append({ - "id": str(config.id), - "name": config.name, - "zammad_url": config.zammad_url, - "chatbot_id": config.chatbot_id, - "is_active": config.is_active, - "created_at": config.created_at.isoformat(), - "updated_at": config.updated_at.isoformat() - }) - - return result - except Exception as e: - self.logger.error(f"Failed to get user configurations: {e}") - return [] - - async def fetch_tickets_from_zammad(self, config: Dict[str, Any]) -> List[Dict[str, Any]]: - """Fetch tickets from Zammad API""" - async with aiohttp.ClientSession() as session: - headers = { - "Authorization": f"Token {config['api_token']}", - "Content-Type": "application/json" - } - - async with session.get( - f"{config['zammad_url']}/api/v1/tickets", - headers=headers, - timeout=30 - ) as response: - if response.status != 200: - raise HTTPException( - status_code=response.status, - detail=f"Zammad API error: {await response.text()}" - ) - - return await response.json() - - async def fetch_ticket_from_zammad(self, config: Dict[str, Any], ticket_id: str) -> Dict[str, Any]: - """Fetch specific ticket from Zammad""" - async with aiohttp.ClientSession() as session: - headers = { - "Authorization": f"Token {config['api_token']}", - "Content-Type": "application/json" - } - - async with session.get( - f"{config['zammad_url']}/api/v1/tickets/{ticket_id}", - headers=headers, - timeout=30 - ) as response: - if response.status != 200: - raise HTTPException( - status_code=response.status, - detail=f"Zammad API error: {await response.text()}" - ) - - return await response.json() - - async def summarize_ticket_async(self, config: Dict[str, Any], ticket_id: str, user_id: str): - """Asynchronously summarize a ticket using platform AI""" - try: - # Get ticket details - ticket = await self.fetch_ticket_from_zammad(config, ticket_id) - - # Use platform chatbot API for summarization - chatbot_response = await self.api_client.call_chatbot_api( - chatbot_id=config["chatbot_id"], - message=f"Summarize this support ticket:\n\nTitle: {ticket.get('title', '')}\n\nContent: {ticket.get('body', '')}" - ) - - summary = chatbot_response.get("response", "") - - # TODO: Store summary in database - self.logger.info(f"Generated summary for ticket {ticket_id}: {summary[:100]}...") - - # Update ticket in Zammad with summary - await self.update_ticket_summary(config, ticket_id, summary) - - except Exception as e: - self.logger.error(f"Error summarizing ticket {ticket_id}: {e}") - - async def update_ticket_summary(self, config: Dict[str, Any], ticket_id: str, summary: str): - """Update ticket with AI summary""" - async with aiohttp.ClientSession() as session: - headers = { - "Authorization": f"Token {config['api_token']}", - "Content-Type": "application/json" - } - - update_data = { - "note": f"AI Summary: {summary}" - } - - async with session.put( - f"{config['zammad_url']}/api/v1/tickets/{ticket_id}", - headers=headers, - json=update_data, - timeout=30 - ) as response: - if response.status not in [200, 201]: - self.logger.error(f"Failed to update ticket {ticket_id} with summary") - - async def test_zammad_connection(self, config: Dict[str, Any]) -> Dict[str, Any]: - """Test connection to Zammad instance""" - try: - async with aiohttp.ClientSession() as session: - headers = { - "Authorization": f"Token {config['api_token']}", - "Content-Type": "application/json" - } - - async with session.get( - f"{config['zammad_url']}/api/v1/users/me", - headers=headers, - timeout=10 - ) as response: - if response.status == 200: - user_data = await response.json() - return { - "success": True, - "user": user_data.get("login", "unknown"), - "zammad_version": response.headers.get("X-Zammad-Version", "unknown") - } - else: - return { - "success": False, - "error": f"HTTP {response.status}: {await response.text()}" - } - - except Exception as e: - return { - "success": False, - "error": str(e) - } - - async def process_ticket_webhook(self, webhook_data: Dict[str, Any]): - """Process ticket webhook asynchronously""" - try: - ticket_data = webhook_data.get("ticket", {}) - ticket_id = ticket_data.get("id") - - self.logger.info(f"Processing webhook for ticket {ticket_id}") - - # TODO: Get configuration and auto-summarize if enabled - # This would require looking up the configuration associated with the webhook - - except Exception as e: - self.logger.error(f"Error processing webhook: {e}") - - # Cron job functions - - async def sync_tickets_from_zammad(self) -> bool: - """Sync tickets from Zammad (cron job)""" - try: - self.logger.info("Starting ticket sync from Zammad") - - # TODO: Get all active configurations and sync tickets - # This would iterate through all user configurations - - self.logger.info("Ticket sync completed successfully") - return True - - except Exception as e: - self.logger.error(f"Ticket sync failed: {e}") - return False - - async def cleanup_old_summaries(self) -> bool: - """Clean up old AI summaries (cron job)""" - try: - self.logger.info("Starting cleanup of old summaries") - - # TODO: Clean up summaries older than retention period - - self.logger.info("Summary cleanup completed") - return True - - except Exception as e: - self.logger.error(f"Summary cleanup failed: {e}") - return False - - async def check_zammad_connection(self) -> bool: - """Check Zammad connectivity (cron job)""" - try: - # TODO: Test all configured Zammad instances - self.logger.info("Zammad connectivity check completed") - return True - - except Exception as e: - self.logger.error(f"Connectivity check failed: {e}") - return False - - async def generate_weekly_reports(self) -> bool: - """Generate weekly reports (cron job)""" - try: - self.logger.info("Generating weekly reports") - - # TODO: Generate and send weekly ticket reports - - self.logger.info("Weekly reports generated successfully") - return True - - except Exception as e: - self.logger.error(f"Report generation failed: {e}") - return False - - # Enhanced database integration methods - - async def _save_configuration_to_db(self, config_data: Dict[str, Any], user_id: str) -> bool: - """Save Zammad configuration to plugin database""" - try: - from app.services.plugin_security import plugin_token_manager - - # Encrypt API token - encrypted_token = plugin_token_manager.encrypt_plugin_secret(config_data["api_token"]) - - async with PluginDatabaseSession(self.plugin_id, plugin_db_manager) as db: - # Deactivate existing configurations if this is set as active - if config_data.get("is_active", True): - await db.query(ZammadConfiguration).filter( - ZammadConfiguration.user_id == user_id, - ZammadConfiguration.is_active == True - ).update({"is_active": False}) - - # Create new configuration - config = ZammadConfiguration( - user_id=user_id, - name=config_data["name"], - zammad_url=config_data["zammad_url"], - api_token_encrypted=encrypted_token, - chatbot_id=config_data["chatbot_id"], - is_active=config_data.get("is_active", True), - ai_summarization_enabled=config_data.get("ai_summarization", {}).get("enabled", True), - auto_summarize=config_data.get("ai_summarization", {}).get("auto_summarize", True), - sync_enabled=config_data.get("sync_settings", {}).get("enabled", True), - sync_interval_hours=config_data.get("sync_settings", {}).get("interval_hours", 2) - ) - - db.add(config) - await db.commit() - - self.logger.info(f"Saved Zammad configuration for user {user_id}") - return True - - except Exception as e: - self.logger.error(f"Failed to save configuration: {e}") - return False - - async def _get_plugin_statistics(self, user_id: str) -> Dict[str, Any]: - """Get plugin usage statistics""" - try: - async with PluginDatabaseSession(self.plugin_id, plugin_db_manager) as db: - # Get configuration count - config_count = await db.query(ZammadConfiguration).filter( - ZammadConfiguration.user_id == user_id - ).count() - - # Get ticket count - ticket_count = await db.query(ZammadTicket).join(ZammadConfiguration).filter( - ZammadConfiguration.user_id == user_id - ).count() - - # Get tickets with AI summaries - summarized_count = await db.query(ZammadTicket).join(ZammadConfiguration).filter( - ZammadConfiguration.user_id == user_id, - ZammadTicket.ai_summary.isnot(None) - ).count() - - # Get recent activity (last 7 days) - from datetime import timedelta - week_ago = datetime.now(timezone.utc) - timedelta(days=7) - recent_tickets = await db.query(ZammadTicket).join(ZammadConfiguration).filter( - ZammadConfiguration.user_id == user_id, - ZammadTicket.last_synced >= week_ago - ).count() - - return { - "configurations": config_count, - "total_tickets": ticket_count, - "tickets_with_summaries": summarized_count, - "recent_tickets": recent_tickets, - "summary_rate": round((summarized_count / max(ticket_count, 1)) * 100, 1), - "last_sync": datetime.now(timezone.utc).isoformat() - } - - except Exception as e: - self.logger.error(f"Failed to get statistics: {e}") - return { - "error": str(e), - "configurations": 0, - "total_tickets": 0, - "tickets_with_summaries": 0, - "recent_tickets": 0, - "summary_rate": 0.0 - } - - async def _sync_user_tickets(self, user_id: str) -> int: - """Sync tickets for a specific user""" - try: - config = await self.get_active_config(user_id) - if not config: - return 0 - - # Fetch tickets from Zammad - tickets = await self.fetch_tickets_from_zammad(config) - synced_count = 0 - - async with PluginDatabaseSession(self.plugin_id, plugin_db_manager) as db: - config_record = await db.query(ZammadConfiguration).filter( - ZammadConfiguration.id == config["id"] - ).first() - - if not config_record: - return 0 - - for ticket_data in tickets: - # Check if ticket already exists - existing_ticket = await db.query(ZammadTicket).filter( - ZammadTicket.zammad_ticket_id == str(ticket_data["id"]), - ZammadTicket.configuration_id == config_record.id - ).first() - - if existing_ticket: - # Update existing ticket - existing_ticket.title = ticket_data.get("title", "") - existing_ticket.body = ticket_data.get("body", "") - existing_ticket.status = ticket_data.get("state", "") - existing_ticket.priority = ticket_data.get("priority", "") - existing_ticket.last_synced = datetime.now(timezone.utc) - existing_ticket.updated_at = datetime.now(timezone.utc) - else: - # Create new ticket - new_ticket = ZammadTicket( - zammad_ticket_id=str(ticket_data["id"]), - configuration_id=config_record.id, - title=ticket_data.get("title", ""), - body=ticket_data.get("body", ""), - status=ticket_data.get("state", ""), - priority=ticket_data.get("priority", ""), - customer_id=str(ticket_data.get("customer_id", "")), - group_id=str(ticket_data.get("group_id", "")), - last_synced=datetime.now(timezone.utc) - ) - db.add(new_ticket) - synced_count += 1 - - await db.commit() - self.logger.info(f"Synced {synced_count} new tickets for user {user_id}") - return synced_count - - except Exception as e: - self.logger.error(f"Failed to sync tickets for user {user_id}: {e}") - return 0 - - async def _store_ticket_summary(self, ticket_id: str, summary: str, config_id: str): - """Store AI-generated summary in database""" - try: - async with PluginDatabaseSession(self.plugin_id, plugin_db_manager) as db: - ticket = await db.query(ZammadTicket).filter( - ZammadTicket.zammad_ticket_id == ticket_id, - ZammadTicket.configuration_id == config_id - ).first() - - if ticket: - ticket.ai_summary = summary - ticket.updated_at = datetime.now(timezone.utc) - await db.commit() - self.logger.info(f"Stored AI summary for ticket {ticket_id}") - - except Exception as e: - self.logger.error(f"Failed to store summary for ticket {ticket_id}: {e}") \ No newline at end of file diff --git a/plugins/zammad/manifest.yaml b/plugins/zammad/manifest.yaml deleted file mode 100644 index 9d419e4..0000000 --- a/plugins/zammad/manifest.yaml +++ /dev/null @@ -1,253 +0,0 @@ -apiVersion: "v1" -kind: "Plugin" -metadata: - name: "zammad" - version: "1.0.0" - description: "Zammad helpdesk integration with AI summarization and ticket management" - author: "Enclava Team" - license: "MIT" - homepage: "https://github.com/enclava/plugins/zammad" - repository: "https://github.com/enclava/plugins/zammad" - tags: - - "helpdesk" - - "ticket-management" - - "ai-summarization" - - "integration" - -spec: - runtime: - python_version: "3.11" - dependencies: - - "aiohttp>=3.8.0" - - "pydantic>=2.0.0" - - "httpx>=0.24.0" - - "python-dateutil>=2.8.0" - environment_variables: - ZAMMAD_TIMEOUT: "30" - ZAMMAD_MAX_RETRIES: "3" - - permissions: - platform_apis: - - "chatbot:invoke" - - "rag:query" - - "llm:completion" - - "llm:embeddings" - plugin_scopes: - - "tickets:read" - - "tickets:write" - - "tickets:summarize" - - "webhooks:receive" - - "config:manage" - - "sync:execute" - external_domains: - - "*.zammad.com" - - "*.zammad.org" - - "api.zammad.org" - - database: - schema: "plugin_zammad" - migrations_path: "./migrations" - auto_migrate: true - - api_endpoints: - - path: "/tickets" - methods: ["GET", "POST"] - description: "List and create Zammad tickets" - auth_required: true - - - path: "/tickets/{ticket_id}" - methods: ["GET", "PUT", "DELETE"] - description: "Get, update, or delete specific ticket" - auth_required: true - - - path: "/tickets/{ticket_id}/summarize" - methods: ["POST"] - description: "Generate AI summary for ticket" - auth_required: true - - - path: "/tickets/{ticket_id}/articles" - methods: ["GET", "POST"] - description: "Get ticket articles or add new article" - auth_required: true - - - path: "/webhooks/ticket-created" - methods: ["POST"] - description: "Handle Zammad webhook for new tickets" - auth_required: false - - - path: "/webhooks/ticket-updated" - methods: ["POST"] - description: "Handle Zammad webhook for updated tickets" - auth_required: false - - - path: "/configurations" - methods: ["GET", "POST", "PUT", "DELETE"] - description: "Manage Zammad configurations" - auth_required: true - - - path: "/configurations/{config_id}/test" - methods: ["POST"] - description: "Test Zammad configuration connection" - auth_required: true - - - path: "/statistics" - methods: ["GET"] - description: "Get plugin usage statistics" - auth_required: true - - - path: "/health" - methods: ["GET"] - description: "Plugin health check" - auth_required: false - - cron_jobs: - - name: "sync_tickets" - schedule: "0 */2 * * *" - function: "sync_tickets_from_zammad" - description: "Sync tickets from Zammad every 2 hours" - enabled: true - timeout_seconds: 600 - max_retries: 3 - - - name: "cleanup_summaries" - schedule: "0 3 * * 0" - function: "cleanup_old_summaries" - description: "Clean up old AI summaries weekly" - enabled: true - timeout_seconds: 300 - max_retries: 1 - - - name: "health_check" - schedule: "*/15 * * * *" - function: "check_zammad_connection" - description: "Check Zammad API connectivity every 15 minutes" - enabled: true - timeout_seconds: 60 - max_retries: 2 - - - name: "generate_reports" - schedule: "0 9 * * 1" - function: "generate_weekly_reports" - description: "Generate weekly ticket reports" - enabled: false - timeout_seconds: 900 - max_retries: 2 - - ui_config: - configuration_schema: "./config_schema.json" - ui_components: "./ui/components" - pages: - - name: "dashboard" - path: "/plugins/zammad" - component: "ZammadDashboard" - - - name: "settings" - path: "/plugins/zammad/settings" - component: "ZammadSettings" - - - name: "tickets" - path: "/plugins/zammad/tickets" - component: "ZammadTicketList" - - - name: "analytics" - path: "/plugins/zammad/analytics" - component: "ZammadAnalytics" - - external_services: - allowed_domains: - - "*.zammad.com" - - "*.zammad.org" - - "api.zammad.org" - - "help.zammad.com" - - webhooks: - - endpoint: "/webhooks/ticket-created" - security: "signature_validation" - - - endpoint: "/webhooks/ticket-updated" - security: "signature_validation" - - rate_limits: - "*.zammad.com": 100 - "*.zammad.org": 100 - "api.zammad.org": 200 - - config_schema: - type: "object" - required: - - "zammad_url" - - "api_token" - - "chatbot_id" - properties: - zammad_url: - type: "string" - format: "uri" - title: "Zammad URL" - description: "The base URL of your Zammad instance" - examples: - - "https://company.zammad.com" - - "https://support.example.com" - - api_token: - type: "string" - title: "API Token" - description: "Zammad API token with ticket read/write permissions" - minLength: 20 - format: "password" - - chatbot_id: - type: "string" - title: "Chatbot ID" - description: "Platform chatbot ID for AI summarization" - examples: - - "zammad-summarizer" - - "ticket-assistant" - - ai_summarization: - type: "object" - title: "AI Summarization Settings" - properties: - enabled: - type: "boolean" - title: "Enable AI Summarization" - description: "Automatically summarize tickets using AI" - default: true - - model: - type: "string" - title: "AI Model" - description: "LLM model to use for summarization" - default: "gpt-3.5-turbo" - - max_tokens: - type: "integer" - title: "Max Summary Tokens" - description: "Maximum tokens for AI summary" - minimum: 50 - maximum: 500 - default: 150 - - draft_settings: - type: "object" - title: "AI Draft Settings" - properties: - enabled: - type: "boolean" - title: "Enable AI Drafts" - description: "Generate AI draft responses for tickets" - default: false - - model: - type: "string" - title: "Draft Model" - description: "LLM model to use for draft generation" - default: "gpt-3.5-turbo" - - max_tokens: - type: "integer" - title: "Max Draft Tokens" - description: "Maximum tokens for AI draft responses" - minimum: 100 - maximum: 1000 - default: 300 - diff --git a/plugins/zammad/migrations/env.py b/plugins/zammad/migrations/env.py deleted file mode 100644 index 28b9fa3..0000000 --- a/plugins/zammad/migrations/env.py +++ /dev/null @@ -1,85 +0,0 @@ -"""Alembic environment for Zammad plugin""" -from logging.config import fileConfig -from sqlalchemy import engine_from_config -from sqlalchemy import pool -from alembic import context -import os -import sys - -# this is the Alembic Config object, which provides -# access to the values within the .ini file in use. -config = context.config - -# Interpret the config file for Python logging. -# This line sets up loggers basically. -if config.config_file_name is not None: - fileConfig(config.config_file_name) - -# add your model's MetaData object here -# for 'autogenerate' support -from main import Base -target_metadata = Base.metadata - -# other values from the config, defined by the needs of env.py, -# can be acquired: -# my_important_option = config.get_main_option("my_important_option") -# ... etc. - - -def run_migrations_offline() -> None: - """Run migrations in 'offline' mode. - - This configures the context with just a URL - and not an Engine, though an Engine is acceptable - here as well. By skipping the Engine creation - we don't even need a DBAPI to be available. - - Calls to context.execute() here emit the given string to the - script output. - - """ - # Get database URL from environment variable - url = os.getenv("DATABASE_URL") - context.configure( - url=url, - target_metadata=target_metadata, - literal_binds=True, - dialect_opts={"paramstyle": "named"}, - ) - - with context.begin_transaction(): - context.run_migrations() - - -def run_migrations_online() -> None: - """Run migrations in 'online' mode. - - In this scenario we need to create an Engine - and associate a connection with the context. - - """ - # Get database URL from environment variable - database_url = os.getenv("DATABASE_URL") - - configuration = config.get_section(config.config_ini_section) - configuration["sqlalchemy.url"] = database_url - - connectable = engine_from_config( - configuration, - prefix="sqlalchemy.", - poolclass=pool.NullPool, - ) - - with connectable.connect() as connection: - context.configure( - connection=connection, target_metadata=target_metadata - ) - - with context.begin_transaction(): - context.run_migrations() - - -if context.is_offline_mode(): - run_migrations_offline() -else: - run_migrations_online() \ No newline at end of file diff --git a/plugins/zammad/migrations/script.py.mako b/plugins/zammad/migrations/script.py.mako deleted file mode 100644 index 37d0cac..0000000 --- a/plugins/zammad/migrations/script.py.mako +++ /dev/null @@ -1,24 +0,0 @@ -"""${message} - -Revision ID: ${up_revision} -Revises: ${down_revision | comma,n} -Create Date: ${create_date} - -""" -from alembic import op -import sqlalchemy as sa -${imports if imports else ""} - -# revision identifiers, used by Alembic. -revision = ${repr(up_revision)} -down_revision = ${repr(down_revision)} -branch_labels = ${repr(branch_labels)} -depends_on = ${repr(depends_on)} - - -def upgrade() -> None: - ${upgrades if upgrades else "pass"} - - -def downgrade() -> None: - ${downgrades if downgrades else "pass"} \ No newline at end of file diff --git a/plugins/zammad/migrations/versions/001_initial_zammad_schema.py b/plugins/zammad/migrations/versions/001_initial_zammad_schema.py deleted file mode 100644 index 8b5ccff..0000000 --- a/plugins/zammad/migrations/versions/001_initial_zammad_schema.py +++ /dev/null @@ -1,112 +0,0 @@ -"""Initial Zammad plugin schema - -Revision ID: 001 -Revises: -Create Date: 2024-12-22 12:00:00.000000 - -""" -from alembic import op -import sqlalchemy as sa -from sqlalchemy.dialects.postgresql import UUID - -# revision identifiers, used by Alembic. -revision = '001' -down_revision = None -branch_labels = None -depends_on = None - - -def upgrade() -> None: - """Create initial Zammad plugin schema""" - - # Create zammad_configurations table - op.create_table( - 'zammad_configurations', - sa.Column('id', UUID(as_uuid=True), primary_key=True, server_default=sa.text('gen_random_uuid()')), - sa.Column('user_id', sa.String(255), nullable=False), - sa.Column('name', sa.String(100), nullable=False), - sa.Column('zammad_url', sa.String(500), nullable=False), - sa.Column('api_token_encrypted', sa.Text(), nullable=False), - sa.Column('chatbot_id', sa.String(100), nullable=False), - sa.Column('is_active', sa.Boolean(), nullable=False, server_default=sa.text('TRUE')), - sa.Column('ai_summarization_enabled', sa.Boolean(), nullable=False, server_default=sa.text('TRUE')), - sa.Column('auto_summarize', sa.Boolean(), nullable=False, server_default=sa.text('TRUE')), - sa.Column('sync_enabled', sa.Boolean(), nullable=False, server_default=sa.text('TRUE')), - sa.Column('sync_interval_hours', sa.Integer(), nullable=False, server_default=sa.text('2')), - sa.Column('created_at', sa.TIMESTAMP(timezone=True), nullable=False, server_default=sa.text('CURRENT_TIMESTAMP')), - sa.Column('updated_at', sa.TIMESTAMP(timezone=True), nullable=False, server_default=sa.text('CURRENT_TIMESTAMP')), - ) - - # Create zammad_tickets table - op.create_table( - 'zammad_tickets', - sa.Column('id', UUID(as_uuid=True), primary_key=True, server_default=sa.text('gen_random_uuid()')), - sa.Column('zammad_ticket_id', sa.String(50), nullable=False), - sa.Column('configuration_id', UUID(as_uuid=True), nullable=True), - sa.Column('title', sa.String(500), nullable=False), - sa.Column('body', sa.Text(), nullable=True), - sa.Column('status', sa.String(50), nullable=True), - sa.Column('priority', sa.String(50), nullable=True), - sa.Column('customer_id', sa.String(50), nullable=True), - sa.Column('group_id', sa.String(50), nullable=True), - sa.Column('ai_summary', sa.Text(), nullable=True), - sa.Column('last_synced', sa.TIMESTAMP(timezone=True), nullable=False, server_default=sa.text('CURRENT_TIMESTAMP')), - sa.Column('created_at', sa.TIMESTAMP(timezone=True), nullable=False, server_default=sa.text('CURRENT_TIMESTAMP')), - sa.Column('updated_at', sa.TIMESTAMP(timezone=True), nullable=False, server_default=sa.text('CURRENT_TIMESTAMP')), - sa.ForeignKeyConstraint(['configuration_id'], ['zammad_configurations.id'], ondelete='CASCADE'), - ) - - # Create indexes for performance - op.create_index('idx_zammad_configurations_user_id', 'zammad_configurations', ['user_id']) - op.create_index('idx_zammad_configurations_user_active', 'zammad_configurations', ['user_id', 'is_active']) - - op.create_index('idx_zammad_tickets_zammad_id', 'zammad_tickets', ['zammad_ticket_id']) - op.create_index('idx_zammad_tickets_config_id', 'zammad_tickets', ['configuration_id']) - op.create_index('idx_zammad_tickets_status', 'zammad_tickets', ['status']) - op.create_index('idx_zammad_tickets_last_synced', 'zammad_tickets', ['last_synced']) - - # Create updated_at trigger function if it doesn't exist - op.execute(""" - CREATE OR REPLACE FUNCTION update_updated_at_column() - RETURNS TRIGGER AS $$ - BEGIN - NEW.updated_at = CURRENT_TIMESTAMP; - RETURN NEW; - END; - $$ LANGUAGE 'plpgsql'; - """) - - # Create triggers to automatically update updated_at columns - op.execute(""" - CREATE TRIGGER update_zammad_configurations_updated_at - BEFORE UPDATE ON zammad_configurations - FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); - """) - - op.execute(""" - CREATE TRIGGER update_zammad_tickets_updated_at - BEFORE UPDATE ON zammad_tickets - FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); - """) - - -def downgrade() -> None: - """Drop Zammad plugin schema""" - - # Drop triggers first - op.execute("DROP TRIGGER IF EXISTS update_zammad_tickets_updated_at ON zammad_tickets;") - op.execute("DROP TRIGGER IF EXISTS update_zammad_configurations_updated_at ON zammad_configurations;") - - # Drop indexes - op.drop_index('idx_zammad_tickets_last_synced') - op.drop_index('idx_zammad_tickets_status') - op.drop_index('idx_zammad_tickets_config_id') - op.drop_index('idx_zammad_tickets_zammad_id') - op.drop_index('idx_zammad_configurations_user_active') - op.drop_index('idx_zammad_configurations_user_id') - - # Drop tables (tickets first due to foreign key) - op.drop_table('zammad_tickets') - op.drop_table('zammad_configurations') - - # Note: We don't drop the update_updated_at_column function as it might be used by other tables \ No newline at end of file diff --git a/plugins/zammad/requirements.txt b/plugins/zammad/requirements.txt deleted file mode 100644 index 47097f2..0000000 --- a/plugins/zammad/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -aiohttp>=3.8.0 -pydantic>=2.0.0 -httpx>=0.24.0 -python-dateutil>=2.8.0 \ No newline at end of file diff --git a/plugins/zammad/ui/components/ZammadDashboard.tsx b/plugins/zammad/ui/components/ZammadDashboard.tsx deleted file mode 100644 index f5f6aec..0000000 --- a/plugins/zammad/ui/components/ZammadDashboard.tsx +++ /dev/null @@ -1,414 +0,0 @@ -/** - * Zammad Plugin Dashboard Component - * Main dashboard for Zammad plugin showing tickets, statistics, and quick actions - */ -import React, { useState, useEffect } from 'react'; -import { - Box, - Grid, - Card, - CardContent, - Typography, - Button, - Chip, - Alert, - Table, - TableBody, - TableCell, - TableHead, - TableRow, - IconButton, - Dialog, - DialogTitle, - DialogContent, - DialogActions, - LinearProgress, - Tooltip -} from '@mui/material'; -import { - Refresh as RefreshIcon, - Sync as SyncIcon, - Analytics as AnalyticsIcon, - Assignment as TicketIcon, - AutoAwesome as AIIcon, - Settings as SettingsIcon, - OpenInNew as OpenIcon -} from '@mui/icons-material'; - -interface ZammadTicket { - id: string; - title: string; - status: string; - priority: string; - customer_id: string; - created_at: string; - ai_summary?: string; -} - -interface ZammadStats { - configurations: number; - total_tickets: number; - tickets_with_summaries: number; - recent_tickets: number; - summary_rate: number; - last_sync: string; -} - -export const ZammadDashboard: React.FC = () => { - const [tickets, setTickets] = useState([]); - const [stats, setStats] = useState(null); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); - const [selectedTicket, setSelectedTicket] = useState(null); - const [dialogOpen, setDialogOpen] = useState(false); - const [syncing, setSyncing] = useState(false); - - useEffect(() => { - loadDashboardData(); - }, []); - - const loadDashboardData = async () => { - setLoading(true); - setError(null); - - try { - // Load statistics - const statsResponse = await fetch('/api/v1/plugins/zammad/statistics'); - if (statsResponse.ok) { - const statsData = await statsResponse.json(); - setStats(statsData); - } - - // Load recent tickets - const ticketsResponse = await fetch('/api/v1/plugins/zammad/tickets?limit=10'); - if (ticketsResponse.ok) { - const ticketsData = await ticketsResponse.json(); - setTickets(ticketsData.tickets || []); - } - - } catch (err) { - setError('Failed to load dashboard data'); - console.error('Dashboard load error:', err); - } finally { - setLoading(false); - } - }; - - const handleSyncTickets = async () => { - setSyncing(true); - try { - const response = await fetch('/api/v1/plugins/zammad/tickets/sync', { - method: 'GET' - }); - - if (response.ok) { - const result = await response.json(); - // Reload dashboard data after sync - await loadDashboardData(); - // Show success message with sync count - console.log(`Synced ${result.synced_count} tickets`); - } else { - throw new Error('Sync failed'); - } - } catch (err) { - setError('Failed to sync tickets'); - } finally { - setSyncing(false); - } - }; - - const handleTicketClick = (ticket: ZammadTicket) => { - setSelectedTicket(ticket); - setDialogOpen(true); - }; - - const handleSummarizeTicket = async (ticketId: string) => { - try { - const response = await fetch(`/api/v1/plugins/zammad/tickets/${ticketId}/summarize`, { - method: 'POST' - }); - - if (response.ok) { - // Show success message - console.log('Summarization started'); - } - } catch (err) { - console.error('Summarization failed:', err); - } - }; - - const getStatusColor = (status: string) => { - switch (status.toLowerCase()) { - case 'open': return 'error'; - case 'pending': return 'warning'; - case 'closed': return 'success'; - default: return 'default'; - } - }; - - const getPriorityColor = (priority: string) => { - switch (priority) { - case '3 high': return 'error'; - case '2 normal': return 'warning'; - case '1 low': return 'success'; - default: return 'default'; - } - }; - - return ( - - {/* Header */} - - - Zammad Dashboard - - - - - - - - - - {error && ( - - {error} - - )} - - {loading && } - - {/* Statistics Cards */} - {stats && ( - - - - - - - - {stats.total_tickets} - - Total Tickets - - - - - - - - - - - - - - {stats.tickets_with_summaries} - - AI Summaries - - - - - - - - - - - - - - {stats.summary_rate}% - - Summary Rate - - - - - - - - - - - - - - {stats.recent_tickets} - - Recent (7 days) - - - - - - - - )} - - {/* Recent Tickets Table */} - - - - Recent Tickets - - - - {tickets.length === 0 ? ( - - No tickets found. Try syncing with Zammad. - - ) : ( - - - - Title - Status - Priority - AI Summary - Actions - - - - {tickets.map((ticket) => ( - handleTicketClick(ticket)}> - - - {ticket.title} - - - - - - - - - - {ticket.ai_summary ? ( - - ) : ( - - )} - - - - { - e.stopPropagation(); - handleSummarizeTicket(ticket.id); - }} - disabled={!!ticket.ai_summary} - > - - - - - - ))} - -
- )} -
-
- - {/* Ticket Detail Dialog */} - setDialogOpen(false)} - maxWidth="md" - fullWidth - > - - Ticket Details - - - - {selectedTicket && ( - - - {selectedTicket.title} - - - - - - - - - Customer: {selectedTicket.customer_id} - - - - Created: {new Date(selectedTicket.created_at).toLocaleString()} - - - {selectedTicket.ai_summary && ( - - - AI Summary - - - {selectedTicket.ai_summary} - - - )} - - )} - - - - - {selectedTicket && !selectedTicket.ai_summary && ( - - )} - - -
- ); -}; \ No newline at end of file diff --git a/plugins/zammad/ui/components/ZammadSettings.tsx b/plugins/zammad/ui/components/ZammadSettings.tsx deleted file mode 100644 index c729d1d..0000000 --- a/plugins/zammad/ui/components/ZammadSettings.tsx +++ /dev/null @@ -1,512 +0,0 @@ -/** - * Zammad Plugin Settings Component - * Configuration interface for Zammad plugin - */ -import React, { useState, useEffect } from 'react'; -import { - Box, - Card, - CardContent, - Typography, - TextField, - Button, - Switch, - FormControlLabel, - FormGroup, - Select, - MenuItem, - FormControl, - InputLabel, - Alert, - Divider, - Accordion, - AccordionSummary, - AccordionDetails, - Chip, - LinearProgress -} from '@mui/material'; -import { - ExpandMore as ExpandMoreIcon, - Save as SaveIcon, - TestTube as TestIcon, - Security as SecurityIcon, - Sync as SyncIcon, - Smart as AIIcon -} from '@mui/icons-material'; - -interface ZammadConfig { - name: string; - zammad_url: string; - api_token: string; - chatbot_id: string; - ai_summarization: { - enabled: boolean; - model: string; - max_tokens: number; - auto_summarize: boolean; - }; - sync_settings: { - enabled: boolean; - interval_hours: number; - sync_articles: boolean; - max_tickets_per_sync: number; - }; - webhook_settings: { - secret: string; - enabled_events: string[]; - }; - notification_settings: { - email_notifications: boolean; - slack_webhook_url: string; - notification_events: string[]; - }; -} - -const defaultConfig: ZammadConfig = { - name: '', - zammad_url: '', - api_token: '', - chatbot_id: '', - ai_summarization: { - enabled: true, - model: 'gpt-3.5-turbo', - max_tokens: 150, - auto_summarize: true - }, - sync_settings: { - enabled: true, - interval_hours: 2, - sync_articles: true, - max_tickets_per_sync: 100 - }, - webhook_settings: { - secret: '', - enabled_events: ['ticket.create', 'ticket.update'] - }, - notification_settings: { - email_notifications: false, - slack_webhook_url: '', - notification_events: ['sync_error', 'api_error'] - } -}; - -export const ZammadSettings: React.FC = () => { - const [config, setConfig] = useState(defaultConfig); - const [loading, setLoading] = useState(false); - const [saving, setSaving] = useState(false); - const [testing, setTesting] = useState(false); - const [error, setError] = useState(null); - const [success, setSuccess] = useState(null); - const [testResult, setTestResult] = useState(null); - - useEffect(() => { - loadConfiguration(); - }, []); - - const loadConfiguration = async () => { - setLoading(true); - try { - const response = await fetch('/api/v1/plugins/zammad/configurations'); - if (response.ok) { - const data = await response.json(); - if (data.configurations.length > 0) { - // Load the first (active) configuration - const loadedConfig = data.configurations[0]; - setConfig({ - ...defaultConfig, - ...loadedConfig - }); - } - } - } catch (err) { - setError('Failed to load configuration'); - } finally { - setLoading(false); - } - }; - - const handleConfigChange = (path: string, value: any) => { - setConfig(prev => { - const newConfig = { ...prev }; - const keys = path.split('.'); - let current: any = newConfig; - - for (let i = 0; i < keys.length - 1; i++) { - current = current[keys[i]]; - } - - current[keys[keys.length - 1]] = value; - return newConfig; - }); - }; - - const handleTestConnection = async () => { - setTesting(true); - setTestResult(null); - setError(null); - - try { - const response = await fetch('/api/v1/plugins/zammad/configurations/test', { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - zammad_url: config.zammad_url, - api_token: config.api_token - }) - }); - - const result = await response.json(); - setTestResult(result); - - if (!result.success) { - setError(`Connection test failed: ${result.error}`); - } - } catch (err) { - setError('Connection test failed'); - } finally { - setTesting(false); - } - }; - - const handleSaveConfiguration = async () => { - setSaving(true); - setError(null); - setSuccess(null); - - try { - const response = await fetch('/api/v1/plugins/zammad/configurations', { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify(config) - }); - - if (response.ok) { - setSuccess('Configuration saved successfully'); - } else { - const errorData = await response.json(); - setError(errorData.detail || 'Failed to save configuration'); - } - } catch (err) { - setError('Failed to save configuration'); - } finally { - setSaving(false); - } - }; - - const handleArrayToggle = (path: string, value: string) => { - const currentArray = path.split('.').reduce((obj, key) => obj[key], config) as string[]; - const newArray = currentArray.includes(value) - ? currentArray.filter(item => item !== value) - : [...currentArray, value]; - handleConfigChange(path, newArray); - }; - - if (loading) { - return ( - - Zammad Settings - - - ); - } - - return ( - - - - Zammad Settings - - - - - - - - - - {error && ( - - {error} - - )} - - {success && ( - - {success} - - )} - - {testResult && ( - - {testResult.success - ? `Connection successful! User: ${testResult.user}, Version: ${testResult.zammad_version}` - : `Connection failed: ${testResult.error}` - } - - )} - - {/* Basic Configuration */} - - - - Basic Configuration - - - - handleConfigChange('name', e.target.value)} - fullWidth - required - /> - - handleConfigChange('zammad_url', e.target.value)} - fullWidth - required - placeholder="https://company.zammad.com" - /> - - handleConfigChange('api_token', e.target.value)} - fullWidth - required - helperText="Zammad API token with ticket read/write permissions" - /> - - handleConfigChange('chatbot_id', e.target.value)} - fullWidth - required - helperText="Platform chatbot ID for AI summarization" - /> - - - - - {/* AI Summarization Settings */} - - }> - - - AI Summarization - - - - - - handleConfigChange('ai_summarization.enabled', e.target.checked)} - /> - } - label="Enable AI Summarization" - /> - - - AI Model - - - - handleConfigChange('ai_summarization.max_tokens', parseInt(e.target.value))} - inputProps={{ min: 50, max: 500 }} - /> - - handleConfigChange('ai_summarization.auto_summarize', e.target.checked)} - /> - } - label="Auto-summarize New Tickets" - /> - - - - - {/* Sync Settings */} - - }> - - - Sync Settings - - - - - - handleConfigChange('sync_settings.enabled', e.target.checked)} - /> - } - label="Enable Automatic Sync" - /> - - handleConfigChange('sync_settings.interval_hours', parseInt(e.target.value))} - inputProps={{ min: 1, max: 24 }} - /> - - handleConfigChange('sync_settings.sync_articles', e.target.checked)} - /> - } - label="Sync Ticket Articles" - /> - - handleConfigChange('sync_settings.max_tickets_per_sync', parseInt(e.target.value))} - inputProps={{ min: 10, max: 1000 }} - /> - - - - - {/* Webhook Settings */} - - }> - - - Webhook Settings - - - - - handleConfigChange('webhook_settings.secret', e.target.value)} - fullWidth - helperText="Secret for webhook signature validation" - /> - - Enabled Webhook Events - - {['ticket.create', 'ticket.update', 'ticket.close', 'article.create'].map((event) => ( - handleArrayToggle('webhook_settings.enabled_events', event)} - /> - } - label={event} - /> - ))} - - - - - - {/* Notification Settings */} - - }> - Notification Settings - - - - handleConfigChange('notification_settings.email_notifications', e.target.checked)} - /> - } - label="Email Notifications" - /> - - handleConfigChange('notification_settings.slack_webhook_url', e.target.value)} - fullWidth - placeholder="https://hooks.slack.com/services/..." - /> - - Notification Events - - {['sync_error', 'api_error', 'new_tickets', 'summarization_complete'].map((event) => ( - handleArrayToggle('notification_settings.notification_events', event)} - /> - } - label={event.replace('_', ' ').replace(/\b\w/g, l => l.toUpperCase())} - /> - ))} - - - - - - ); -}; \ No newline at end of file From 5322b17a780e96220521efdf4213a66bca23489b Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Mon, 15 Sep 2025 09:34:46 +0200 Subject: [PATCH 02/43] orphaned plugin cleanup --- backend/app/services/plugin_registry.py | 13 +- backend/scripts/cleanup_orphaned_plugin.py | 162 +++++++++++++++++++++ 2 files changed, 172 insertions(+), 3 deletions(-) create mode 100755 backend/scripts/cleanup_orphaned_plugin.py diff --git a/backend/app/services/plugin_registry.py b/backend/app/services/plugin_registry.py index fc550c3..e95aeb6 100644 --- a/backend/app/services/plugin_registry.py +++ b/backend/app/services/plugin_registry.py @@ -398,19 +398,26 @@ class PluginInstaller: if plugin_id in plugin_loader.loaded_plugins: await plugin_loader.unload_plugin(plugin_id) - # Backup data if requested + # Backup data if requested (handle missing files gracefully) backup_path = None if keep_data: - backup_path = await plugin_db_manager.backup_plugin_data(plugin_id) + try: + backup_path = await plugin_db_manager.backup_plugin_data(plugin_id) + except Exception as e: + logger.warning(f"Could not backup plugin data (files may be missing): {e}") + # Continue with uninstall even if backup fails # Delete database schema if not keeping data if not keep_data: await plugin_db_manager.delete_plugin_schema(plugin_id) - # Remove plugin files + # Remove plugin files (handle missing directories gracefully) plugin_dir = self.plugins_dir / plugin_id if plugin_dir.exists(): shutil.rmtree(plugin_dir) + logger.info(f"Removed plugin directory: {plugin_dir}") + else: + logger.warning(f"Plugin directory not found (already removed?): {plugin_dir}") # Update database plugin.status = "uninstalled" diff --git a/backend/scripts/cleanup_orphaned_plugin.py b/backend/scripts/cleanup_orphaned_plugin.py new file mode 100755 index 0000000..df74580 --- /dev/null +++ b/backend/scripts/cleanup_orphaned_plugin.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 +""" +Script to clean up orphaned plugin registrations from the database +when plugin files have been manually removed from the filesystem. + +Usage: + python cleanup_orphaned_plugin.py [plugin_name_or_id] + + If no plugin name/id is provided, it will list all orphaned plugins + and prompt for confirmation to clean them up. +""" + +import sys +import os +import asyncio +from pathlib import Path +from uuid import UUID + +# Add backend directory to path +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +from sqlalchemy import select, delete +from sqlalchemy.ext.asyncio import AsyncSession +from app.db.database import async_session_factory, engine +from app.models.plugin import Plugin +from app.core.config import settings +from app.core.logging import get_logger + +logger = get_logger("plugin.cleanup") + + +async def find_orphaned_plugins(session: AsyncSession): + """Find plugins registered in database but missing from filesystem""" + plugins_dir = Path(settings.PLUGINS_DIR or "/plugins") + + # Get all plugins from database + stmt = select(Plugin) + result = await session.execute(stmt) + all_plugins = result.scalars().all() + + orphaned = [] + for plugin in all_plugins: + # Check if plugin directory exists + plugin_path = plugins_dir / str(plugin.id) + if not plugin_path.exists(): + orphaned.append(plugin) + logger.info(f"Found orphaned plugin: {plugin.name} (ID: {plugin.id})") + + return orphaned + + +async def cleanup_plugin(session: AsyncSession, plugin: Plugin, keep_data: bool = True): + """Clean up a single orphaned plugin registration""" + try: + logger.info(f"Cleaning up plugin: {plugin.name} (ID: {plugin.id})") + + # Delete plugin configurations if they exist + try: + from app.models.plugin_configuration import PluginConfiguration + config_stmt = delete(PluginConfiguration).where( + PluginConfiguration.plugin_id == plugin.id + ) + await session.execute(config_stmt) + logger.info(f"Deleted configurations for plugin {plugin.id}") + except ImportError: + pass # Plugin configuration model might not exist + + # Delete the plugin record + await session.delete(plugin) + await session.commit() + + logger.info(f"Successfully cleaned up plugin: {plugin.name}") + return True + + except Exception as e: + logger.error(f"Failed to cleanup plugin {plugin.name}: {e}") + await session.rollback() + return False + + +async def main(): + """Main cleanup function""" + target_plugin = sys.argv[1] if len(sys.argv) > 1 else None + + async with async_session_factory() as session: + if target_plugin: + # Clean up specific plugin + try: + # Try to parse as UUID first + plugin_id = UUID(target_plugin) + stmt = select(Plugin).where(Plugin.id == plugin_id) + except ValueError: + # Not a UUID, search by name + stmt = select(Plugin).where(Plugin.name == target_plugin) + + result = await session.execute(stmt) + plugin = result.scalar_one_or_none() + + if not plugin: + print(f"Plugin '{target_plugin}' not found in database") + return + + # Check if plugin directory exists + plugins_dir = Path(settings.PLUGINS_DIR or "/plugins") + plugin_path = plugins_dir / str(plugin.id) + + if plugin_path.exists(): + print(f"Plugin directory exists at {plugin_path}") + response = input("Plugin files exist. Are you sure you want to cleanup the database entry? (y/N): ") + if response.lower() != 'y': + print("Cleanup cancelled") + return + + print(f"\nFound plugin:") + print(f" Name: {plugin.name}") + print(f" ID: {plugin.id}") + print(f" Version: {plugin.version}") + print(f" Status: {plugin.status}") + print(f" Directory: {plugin_path} (exists: {plugin_path.exists()})") + + response = input("\nProceed with cleanup? (y/N): ") + if response.lower() == 'y': + success = await cleanup_plugin(session, plugin) + if success: + print("✓ Plugin cleaned up successfully") + else: + print("✗ Failed to cleanup plugin") + else: + print("Cleanup cancelled") + + else: + # List all orphaned plugins + orphaned = await find_orphaned_plugins(session) + + if not orphaned: + print("No orphaned plugins found") + return + + print(f"\nFound {len(orphaned)} orphaned plugin(s):") + for plugin in orphaned: + plugins_dir = Path(settings.PLUGINS_DIR or "/plugins") + plugin_path = plugins_dir / str(plugin.id) + print(f"\n • {plugin.name}") + print(f" ID: {plugin.id}") + print(f" Version: {plugin.version}") + print(f" Status: {plugin.status}") + print(f" Expected path: {plugin_path}") + + response = input(f"\nCleanup all {len(orphaned)} orphaned plugin(s)? (y/N): ") + if response.lower() == 'y': + success_count = 0 + for plugin in orphaned: + if await cleanup_plugin(session, plugin): + success_count += 1 + + print(f"\n✓ Cleaned up {success_count}/{len(orphaned)} plugin(s)") + else: + print("Cleanup cancelled") + + +if __name__ == "__main__": + asyncio.run(main()) \ No newline at end of file From 9753fbb567ffdf8b4a6fb18296ff415f360faaae Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Mon, 15 Sep 2025 17:10:24 +0200 Subject: [PATCH 03/43] fixing llm settings --- frontend/src/app/llm/page.tsx | 96 ----------------------------------- 1 file changed, 96 deletions(-) diff --git a/frontend/src/app/llm/page.tsx b/frontend/src/app/llm/page.tsx index 766f7be..7789842 100644 --- a/frontend/src/app/llm/page.tsx +++ b/frontend/src/app/llm/page.tsx @@ -18,7 +18,6 @@ import { Plus, Settings, Trash2, - Copy, Calendar, Lock, Unlock, @@ -187,15 +186,6 @@ function LLMPageContent() { } } - const copyToClipboard = (text: string, type: string = "API key") => { - navigator.clipboard.writeText(text) - toast({ - title: "Copied!", - description: `${type} copied to clipboard` - }) - } - - const formatCurrency = (cents: number) => { return `$${(cents / 100).toFixed(4)}` } @@ -205,21 +195,6 @@ function LLMPageContent() { return new Date(dateStr).toLocaleDateString() } - - // Get the public API URL from the current window location - const getPublicApiUrl = () => { - if (typeof window !== 'undefined') { - const protocol = window.location.protocol - const hostname = window.location.hostname - const port = window.location.port || (protocol === 'https:' ? '443' : '80') - const portSuffix = (protocol === 'https:' && port === '443') || (protocol === 'http:' && port === '80') ? '' : `:${port}` - return `${protocol}//${hostname}${portSuffix}/api/v1` - } - return 'http://localhost/api/v1' - } - - const publicApiUrl = getPublicApiUrl() - return (
@@ -229,77 +204,6 @@ function LLMPageContent() {

- {/* Public API URL Display */} - - - - - OpenAI-Compatible API Configuration - - - Use this endpoint URL to configure external tools like Open WebUI, Continue.dev, or any OpenAI-compatible client. - - - -
-
- -
- - {publicApiUrl} - - -
-
- -
-
-

Available Endpoints:

-
    -
  • GET /v1/models - List available models
  • -
  • POST /v1/chat/completions - Chat completions
  • -
  • POST /v1/embeddings - Text embeddings
  • -
-
- -
-

Configuration Example:

-
-
Base URL: {publicApiUrl}
-
API Key: ce_your_api_key
-
Model: gpt-3.5-turbo
-
-
-
- -
-
- -
- Setup Instructions: -
- 1. Copy the API Base URL above -
- 2. Create an API key in the "API Keys" tab below -
- 3. Use both in your OpenAI-compatible client configuration -
- 4. Do NOT append additional paths like "/models" - clients handle this automatically -
-
-
-
-
-
- API Keys From 2876f0a6088276f175a4492a49571d25c73fc540 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Mon, 15 Sep 2025 17:21:49 +0200 Subject: [PATCH 04/43] docker build fix --- backend/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index aaa4fe6..bc5325f 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -9,7 +9,7 @@ ENV PYTHONPATH=/app WORKDIR /app # Install system dependencies -RUN apt-get update && apt-get install -y \ +RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y \ build-essential \ libpq-dev \ postgresql-client \ From 6efad75714bd04e6d120e2ec3ef7a3cc4126e1a1 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Mon, 15 Sep 2025 18:15:10 +0200 Subject: [PATCH 05/43] prod config docker --- backend/Dockerfile.prod | 53 ++++++++++++ docker-compose.prod.yml | 183 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 236 insertions(+) create mode 100644 backend/Dockerfile.prod create mode 100644 docker-compose.prod.yml diff --git a/backend/Dockerfile.prod b/backend/Dockerfile.prod new file mode 100644 index 0000000..a96b0d7 --- /dev/null +++ b/backend/Dockerfile.prod @@ -0,0 +1,53 @@ +FROM python:3.11-slim + +# Set environment variables +ENV PYTHONUNBUFFERED=1 +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONPATH=/app +ENV NODE_ENV=production +ENV APP_ENV=production + +# Set work directory +WORKDIR /app + +# Install system dependencies +RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y \ + build-essential \ + libpq-dev \ + postgresql-client \ + curl \ + ffmpeg \ + && rm -rf /var/lib/apt/lists/* + +# Copy requirements and install Python dependencies +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# Optional: Install NLP requirements if needed +# COPY requirements-nlp.txt . +# RUN pip install --no-cache-dir -r requirements-nlp.txt + +# Copy application code +COPY . . + +# Copy and make migration script executable +COPY scripts/migrate.sh /usr/local/bin/migrate.sh +RUN chmod +x /usr/local/bin/migrate.sh + +# Create non-root user for security +RUN useradd --create-home --shell /bin/bash app && \ + chown -R app:app /app +USER app + +# Create logs directory +RUN mkdir -p logs + +# Expose port +EXPOSE 8000 + +# Health check +HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \ + CMD curl -f http://localhost:8000/health || exit 1 + +# Run the application in production mode +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] \ No newline at end of file diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..1d2166a --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,183 @@ +version: '3.8' + +services: + # Nginx reverse proxy - Internal routing only (since SSL is handled by host) + enclava-nginx: + image: nginx:alpine + ports: + - "50080:80" # Port for host reverse proxy to connect to + volumes: + - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro + - nginx-logs:/var/log/nginx + depends_on: + - enclava-backend + - enclava-frontend + networks: + - enclava-net + restart: unless-stopped + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost/health"] + interval: 30s + timeout: 10s + retries: 3 + + # Database migration service - runs once to apply migrations + enclava-migrate: + build: + context: ./backend + dockerfile: Dockerfile.prod + environment: + - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@enclava-postgres:5432/${POSTGRES_DB} + depends_on: + - enclava-postgres + command: ["/usr/local/bin/migrate.sh"] + networks: + - enclava-net + restart: "no" # Run once and exit + + # Main application backend - Production version + enclava-backend: + build: + context: ./backend + dockerfile: Dockerfile.prod + environment: + - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@enclava-postgres:5432/${POSTGRES_DB} + - REDIS_URL=redis://enclava-redis:6379 + - QDRANT_HOST=enclava-qdrant + - JWT_SECRET=${JWT_SECRET} + - PRIVATEMODE_API_KEY=${PRIVATEMODE_API_KEY} + - ADMIN_EMAIL=${ADMIN_EMAIL} + - ADMIN_PASSWORD=${ADMIN_PASSWORD} + - LOG_LLM_PROMPTS=${LOG_LLM_PROMPTS:-false} + - BASE_URL=${BASE_URL} + - NODE_ENV=production + - APP_ENV=production + depends_on: + - enclava-migrate + - enclava-postgres + - enclava-redis + - enclava-qdrant + - privatemode-proxy + volumes: + - ./logs:/app/logs + - ./plugins:/plugins + networks: + - enclava-net + restart: unless-stopped + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8000/health"] + interval: 30s + timeout: 10s + retries: 3 + + # Next.js frontend - Production build + enclava-frontend: + build: + context: ./frontend + dockerfile: Dockerfile + target: runner # Use the production stage from multi-stage build + environment: + - BASE_URL=${BASE_URL} + - NEXT_PUBLIC_BASE_URL=${BASE_URL} + - BACKEND_INTERNAL_PORT=8000 + - FRONTEND_INTERNAL_PORT=3000 + - INTERNAL_API_URL=http://enclava-backend:8000 + - NODE_ENV=production + - NEXT_TELEMETRY_DISABLED=1 + depends_on: + - enclava-backend + networks: + - enclava-net + restart: unless-stopped + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:3000"] + interval: 30s + timeout: 10s + retries: 3 + + # PostgreSQL database + enclava-postgres: + image: postgres:16-alpine + environment: + - POSTGRES_DB=${POSTGRES_DB} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + volumes: + - enclava-postgres-data:/var/lib/postgresql/data + - ./postgres/postgresql.conf:/etc/postgresql/postgresql.conf:ro + - postgres-backups:/backups + networks: + - enclava-net + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] + interval: 30s + timeout: 10s + retries: 5 + + # Redis for caching and message queue + enclava-redis: + image: redis:7-alpine + command: redis-server --appendonly yes --maxmemory 512mb --maxmemory-policy allkeys-lru + volumes: + - enclava-redis-data:/data + networks: + - enclava-net + restart: unless-stopped + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 30s + timeout: 10s + retries: 3 + + # Qdrant vector database + enclava-qdrant: + image: qdrant/qdrant:v1.7.4 + environment: + - QDRANT__SERVICE__HTTP_PORT=6333 + - QDRANT__SERVICE__GRPC_PORT=6334 + - QDRANT__LOG_LEVEL=INFO + volumes: + - enclava-qdrant-data:/qdrant/storage + - ./qdrant/config.yaml:/qdrant/config/production.yaml:ro + networks: + - enclava-net + restart: unless-stopped + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:6333/"] + interval: 30s + timeout: 10s + retries: 3 + + # Privatemode.ai service (optional - for confidential models) + privatemode-proxy: + image: ghcr.io/edgelesssys/privatemode/privatemode-proxy:latest + environment: + - PRIVATEMODE_API_KEY=${PRIVATEMODE_API_KEY} + - PRIVATEMODE_CACHE_MODE=${PRIVATEMODE_CACHE_MODE:-none} + - PRIVATEMODE_CACHE_SALT=${PRIVATEMODE_CACHE_SALT} + entrypoint: ["/bin/privatemode-proxy"] + command: [ + "--apiKey=${PRIVATEMODE_API_KEY}", + "--port=8080" + ] + networks: + - enclava-net + restart: unless-stopped + profiles: + - privatemode + + +volumes: + enclava-postgres-data: + driver: local + enclava-redis-data: + driver: local + enclava-qdrant-data: + driver: local + nginx-logs: + driver: local + +networks: + enclava-net: + driver: bridge \ No newline at end of file From 33987c5652902530064eef480718f43ea9e4fb1b Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Mon, 15 Sep 2025 18:44:11 +0200 Subject: [PATCH 06/43] compose prod tuning --- .env.example | 4 +++- docker-compose.prod.yml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index cf6d8f1..fed060d 100644 --- a/.env.example +++ b/.env.example @@ -9,7 +9,9 @@ # =================================== DATABASE_URL=postgresql://enclava_user:enclava_pass@enclava-postgres:5432/enclava_db REDIS_URL=redis://enclava-redis:6379 - +POSTGRES_DB=enclava_db +POSTGRES_USER=enclava_user +POSTGRES_PASSWORD=enclava_pass # =================================== # SECURITY CRITICAL (Required) # =================================== diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 1d2166a..329458b 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -155,7 +155,7 @@ services: environment: - PRIVATEMODE_API_KEY=${PRIVATEMODE_API_KEY} - PRIVATEMODE_CACHE_MODE=${PRIVATEMODE_CACHE_MODE:-none} - - PRIVATEMODE_CACHE_SALT=${PRIVATEMODE_CACHE_SALT} + - PRIVATEMODE_CACHE_SALT=${PRIVATEMODE_CACHE_SALT:-} entrypoint: ["/bin/privatemode-proxy"] command: [ "--apiKey=${PRIVATEMODE_API_KEY}", From 91e86a74deb074fdb0e67397f1562ebe46cafe77 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Mon, 15 Sep 2025 18:45:47 +0200 Subject: [PATCH 07/43] orphaned volume removal --- docker-compose.prod.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 329458b..dd019aa 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -105,7 +105,6 @@ services: volumes: - enclava-postgres-data:/var/lib/postgresql/data - ./postgres/postgresql.conf:/etc/postgresql/postgresql.conf:ro - - postgres-backups:/backups networks: - enclava-net restart: unless-stopped From 3c7fc63ca83c488c52f36f21577648ef49c50fd2 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Mon, 15 Sep 2025 19:08:06 +0200 Subject: [PATCH 08/43] prod build fix --- docker-compose.prod.yml | 3 --- frontend/next.config.js | 7 +++++++ frontend/package-lock.json | 6 +++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index dd019aa..3afaa4c 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -163,10 +163,7 @@ services: networks: - enclava-net restart: unless-stopped - profiles: - - privatemode - volumes: enclava-postgres-data: driver: local diff --git a/frontend/next.config.js b/frontend/next.config.js index 488de78..e70c81f 100644 --- a/frontend/next.config.js +++ b/frontend/next.config.js @@ -11,6 +11,13 @@ const nextConfig = { }, experimental: { }, + webpack: (config) => { + config.resolve.alias = { + ...config.resolve.alias, + '@': require('path').resolve(__dirname, 'src'), + }; + return config; + }, env: { NEXT_PUBLIC_BASE_URL: process.env.NEXT_PUBLIC_BASE_URL, NEXT_PUBLIC_APP_NAME: process.env.NEXT_PUBLIC_APP_NAME || 'Enclava', // Sane default diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 5f8f91b..b5af4b6 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -2613,9 +2613,9 @@ } }, "node_modules/axios": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", - "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", + "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", From 407e14faa6c0960028ed106cd850f670e134e6b8 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Mon, 15 Sep 2025 20:10:29 +0200 Subject: [PATCH 09/43] Fix Docker build with Next.js standalone output - Enable outputStandalone in next.config.js for better Docker compatibility - Update Dockerfile to properly copy standalone output files - Change CMD to use node server.js for standalone builds - This should resolve the @/lib module resolution issues in Docker builds --- frontend/Dockerfile | 10 +++++----- frontend/next.config.js | 12 ++++++++++-- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 9627542..8531b34 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -48,10 +48,10 @@ RUN adduser --system --uid 1001 nextjs # Copy node_modules from deps stage COPY --from=deps /app/node_modules ./node_modules -# Copy built application +# Copy built application (standalone output) COPY --from=builder /app/public ./public -COPY --from=builder /app/.next ./.next -COPY --from=builder /app/package.json ./package.json +COPY --from=builder /app/.next/standalone ./ +COPY --from=builder /app/.next/static ./.next/static # Set the correct permission for prerender cache RUN chown -R nextjs:nodejs .next @@ -64,5 +64,5 @@ EXPOSE 3000 ENV PORT 3000 ENV HOSTNAME "0.0.0.0" -# Start the application -CMD ["npm", "start"] \ No newline at end of file +# Start the application (standalone) +CMD ["node", "server.js"] \ No newline at end of file diff --git a/frontend/next.config.js b/frontend/next.config.js index e70c81f..279e0a5 100644 --- a/frontend/next.config.js +++ b/frontend/next.config.js @@ -10,12 +10,20 @@ const nextConfig = { ignoreBuildErrors: true, }, experimental: { + // Enable standalone output for better Docker compatibility + outputStandalone: true, }, - webpack: (config) => { + webpack: (config, { isServer, dev }) => { config.resolve.alias = { ...config.resolve.alias, - '@': require('path').resolve(__dirname, 'src'), + '@': require('path').join(__dirname, 'src'), }; + + // Optional: Add debug logging + if (dev) { + console.log('Webpack alias config:', config.resolve.alias); + } + return config; }, env: { From c4c6643fd13637168837bea9a2d9847be77d4047 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Tue, 16 Sep 2025 07:22:15 +0200 Subject: [PATCH 10/43] Replace @/lib imports in app pages with relative paths - Updated main page components to use relative imports instead of @ aliases - Replaced @/lib/api-client with ../lib/api-client - Replaced @/lib/file-download with ../lib/file-download - This fixes Docker build module resolution issues --- frontend/src/app/admin/page.tsx | 2 +- frontend/src/app/analytics/page.tsx | 2 +- frontend/src/app/api-keys/page.tsx | 2 +- frontend/src/app/audit/page.tsx | 4 ++-- frontend/src/app/budgets/page.tsx | 2 +- frontend/src/app/dashboard/page.tsx | 2 +- frontend/src/app/llm/page.tsx | 2 +- frontend/src/app/prompt-templates/page.tsx | 2 +- frontend/src/app/rag/page.tsx | 2 +- frontend/src/app/register/page.tsx | 2 +- frontend/src/app/settings/page.tsx | 2 +- frontend/src/app/test-auth/page.tsx | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/frontend/src/app/admin/page.tsx b/frontend/src/app/admin/page.tsx index f6b073f..9949f52 100644 --- a/frontend/src/app/admin/page.tsx +++ b/frontend/src/app/admin/page.tsx @@ -18,7 +18,7 @@ import { CheckCircle, XCircle } from "lucide-react"; -import { apiClient } from "@/lib/api-client"; +import { apiClient } from "../lib/api-client"; interface SystemStats { total_users: number; diff --git a/frontend/src/app/analytics/page.tsx b/frontend/src/app/analytics/page.tsx index f82ede2..a9558fe 100644 --- a/frontend/src/app/analytics/page.tsx +++ b/frontend/src/app/analytics/page.tsx @@ -20,7 +20,7 @@ import { RefreshCw } from 'lucide-react'; import { ProtectedRoute } from '@/components/auth/ProtectedRoute' -import { apiClient } from '@/lib/api-client' +import { apiClient } from '../lib/api-client' interface AnalyticsData { overview: { diff --git a/frontend/src/app/api-keys/page.tsx b/frontend/src/app/api-keys/page.tsx index e62e2c7..7eda2ac 100644 --- a/frontend/src/app/api-keys/page.tsx +++ b/frontend/src/app/api-keys/page.tsx @@ -36,7 +36,7 @@ import { Bot } from "lucide-react"; import { useToast } from "@/hooks/use-toast"; -import { apiClient } from "@/lib/api-client"; +import { apiClient } from "../lib/api-client"; interface ApiKey { id: string; diff --git a/frontend/src/app/audit/page.tsx b/frontend/src/app/audit/page.tsx index 4f53420..d4b513d 100644 --- a/frontend/src/app/audit/page.tsx +++ b/frontend/src/app/audit/page.tsx @@ -1,7 +1,7 @@ "use client"; import { useState, useEffect } from "react"; -import { downloadFile } from "@/lib/file-download"; +import { downloadFile } from "../lib/file-download"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; @@ -27,7 +27,7 @@ import { ChevronRight } from "lucide-react"; import { useToast } from "@/hooks/use-toast"; -import { apiClient } from "@/lib/api-client"; +import { apiClient } from "../lib/api-client"; import { config } from "@/lib/config"; interface AuditLog { diff --git a/frontend/src/app/budgets/page.tsx b/frontend/src/app/budgets/page.tsx index 7a1a538..7e9a761 100644 --- a/frontend/src/app/budgets/page.tsx +++ b/frontend/src/app/budgets/page.tsx @@ -34,7 +34,7 @@ import { Clock } from "lucide-react"; import { useToast } from "@/hooks/use-toast"; -import { apiClient } from "@/lib/api-client"; +import { apiClient } from "../lib/api-client"; interface Budget { id: string; diff --git a/frontend/src/app/dashboard/page.tsx b/frontend/src/app/dashboard/page.tsx index f95fabf..d878c49 100644 --- a/frontend/src/app/dashboard/page.tsx +++ b/frontend/src/app/dashboard/page.tsx @@ -5,7 +5,7 @@ import { useState, useEffect } from "react" import { ProtectedRoute } from "@/components/auth/ProtectedRoute" import { useToast } from "@/hooks/use-toast" import { config } from "@/lib/config" -import { apiClient } from "@/lib/api-client" +import { apiClient } from "../lib/api-client" // Force dynamic rendering for authentication export const dynamic = 'force-dynamic' diff --git a/frontend/src/app/llm/page.tsx b/frontend/src/app/llm/page.tsx index 7789842..117b18a 100644 --- a/frontend/src/app/llm/page.tsx +++ b/frontend/src/app/llm/page.tsx @@ -25,7 +25,7 @@ import { AlertTriangle } from 'lucide-react' import { useToast } from '@/hooks/use-toast' -import { apiClient } from '@/lib/api-client' +import { apiClient } from '../lib/api-client' import { ProtectedRoute } from '@/components/auth/ProtectedRoute' import { useRouter } from 'next/navigation' diff --git a/frontend/src/app/prompt-templates/page.tsx b/frontend/src/app/prompt-templates/page.tsx index 7d33758..3232aad 100644 --- a/frontend/src/app/prompt-templates/page.tsx +++ b/frontend/src/app/prompt-templates/page.tsx @@ -29,7 +29,7 @@ import { } from '@/components/ui/alert-dialog' import { Edit3, RotateCcw, Loader2, Save, AlertTriangle, Plus, Sparkles } from 'lucide-react' import toast from 'react-hot-toast' -import { apiClient } from '@/lib/api-client' +import { apiClient } from '../lib/api-client' import { config } from '@/lib/config' import { useAuth } from '@/contexts/AuthContext' diff --git a/frontend/src/app/rag/page.tsx b/frontend/src/app/rag/page.tsx index 87616c1..4eba5ef 100644 --- a/frontend/src/app/rag/page.tsx +++ b/frontend/src/app/rag/page.tsx @@ -13,7 +13,7 @@ import { DocumentUpload } from "@/components/rag/document-upload" import { DocumentBrowser } from "@/components/rag/document-browser" import { useAuth } from "@/contexts/AuthContext" import { ProtectedRoute } from '@/components/auth/ProtectedRoute' -import { apiClient } from '@/lib/api-client' +import { apiClient } from '../lib/api-client' interface Collection { id: string diff --git a/frontend/src/app/register/page.tsx b/frontend/src/app/register/page.tsx index 37c5b53..53ece3f 100644 --- a/frontend/src/app/register/page.tsx +++ b/frontend/src/app/register/page.tsx @@ -10,7 +10,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/com import { Alert, AlertDescription } from "@/components/ui/alert"; import { Checkbox } from "@/components/ui/checkbox"; import { useToast } from "@/hooks/use-toast"; -import { apiClient } from "@/lib/api-client"; +import { apiClient } from "../lib/api-client"; interface RegisterFormData { username: string; diff --git a/frontend/src/app/settings/page.tsx b/frontend/src/app/settings/page.tsx index 4205e8c..c5cf425 100644 --- a/frontend/src/app/settings/page.tsx +++ b/frontend/src/app/settings/page.tsx @@ -31,7 +31,7 @@ import { Play } from "lucide-react"; import { useToast } from "@/hooks/use-toast"; -import { apiClient } from "@/lib/api-client"; +import { apiClient } from "../lib/api-client"; import { useModules, triggerModuleRefresh } from '@/contexts/ModulesContext'; import { Badge } from '@/components/ui/badge'; diff --git a/frontend/src/app/test-auth/page.tsx b/frontend/src/app/test-auth/page.tsx index 003f34c..15935d8 100644 --- a/frontend/src/app/test-auth/page.tsx +++ b/frontend/src/app/test-auth/page.tsx @@ -4,7 +4,7 @@ import { useAuth } from "@/contexts/AuthContext" import { Button } from "@/components/ui/button" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { useState } from "react" -import { apiClient } from "@/lib/api-client" +import { apiClient } from "../lib/api-client" import { tokenManager } from "@/lib/token-manager" export default function TestAuthPage() { From 56a88f0a684ffa1dab53bc8315d92d289a72cab5 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Tue, 16 Sep 2025 08:06:27 +0200 Subject: [PATCH 11/43] build fix --- frontend/Dockerfile | 14 +++++++------- frontend/next.config.js | 8 +++----- frontend/src/app/admin/page.tsx | 4 ++-- frontend/src/app/analytics/page.tsx | 4 ++-- frontend/src/app/api-keys/page.tsx | 17 +++++++++++++---- frontend/src/app/audit/page.tsx | 6 +++--- frontend/src/app/budgets/page.tsx | 4 ++-- frontend/src/app/dashboard/page.tsx | 4 ++-- frontend/src/app/llm/page.tsx | 4 ++-- frontend/src/app/prompt-templates/page.tsx | 4 ++-- frontend/src/app/rag/page.tsx | 4 ++-- frontend/src/app/register/page.tsx | 4 ++-- frontend/src/app/settings/page.tsx | 4 ++-- frontend/src/app/test-auth/page.tsx | 4 ++-- 14 files changed, 46 insertions(+), 39 deletions(-) diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 8531b34..5c26a2e 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -23,8 +23,8 @@ COPY --from=deps /app/node_modules ./node_modules COPY . . # Environment variables for build -ENV NEXT_TELEMETRY_DISABLED 1 -ENV NODE_ENV production +ENV NEXT_TELEMETRY_DISABLED=1 +ENV NODE_ENV=production # Build the application RUN \ @@ -38,8 +38,8 @@ RUN \ FROM base AS runner WORKDIR /app -ENV NODE_ENV production -ENV NEXT_TELEMETRY_DISABLED 1 +ENV NODE_ENV=production +ENV NEXT_TELEMETRY_DISABLED=1 # Create nextjs user RUN addgroup --system --gid 1001 nodejs @@ -61,8 +61,8 @@ USER nextjs # Expose port EXPOSE 3000 -ENV PORT 3000 -ENV HOSTNAME "0.0.0.0" +ENV PORT=3000 +ENV HOSTNAME=0.0.0.0 # Start the application (standalone) -CMD ["node", "server.js"] \ No newline at end of file +CMD ["node", "server.js"] diff --git a/frontend/next.config.js b/frontend/next.config.js index 279e0a5..32baf9a 100644 --- a/frontend/next.config.js +++ b/frontend/next.config.js @@ -9,10 +9,8 @@ const nextConfig = { typescript: { ignoreBuildErrors: true, }, - experimental: { - // Enable standalone output for better Docker compatibility - outputStandalone: true, - }, + // Enable standalone output for better Docker compatibility + output: 'standalone', webpack: (config, { isServer, dev }) => { config.resolve.alias = { ...config.resolve.alias, @@ -53,4 +51,4 @@ const nextConfig = { }, }; -module.exports = nextConfig; \ No newline at end of file +module.exports = nextConfig; diff --git a/frontend/src/app/admin/page.tsx b/frontend/src/app/admin/page.tsx index 9949f52..b8934b2 100644 --- a/frontend/src/app/admin/page.tsx +++ b/frontend/src/app/admin/page.tsx @@ -18,7 +18,7 @@ import { CheckCircle, XCircle } from "lucide-react"; -import { apiClient } from "../lib/api-client"; +import { apiClient } from "@/lib/api-client"; interface SystemStats { total_users: number; @@ -358,4 +358,4 @@ export default function AdminPage() {
); -} \ No newline at end of file +} diff --git a/frontend/src/app/analytics/page.tsx b/frontend/src/app/analytics/page.tsx index a9558fe..ffabd0e 100644 --- a/frontend/src/app/analytics/page.tsx +++ b/frontend/src/app/analytics/page.tsx @@ -20,7 +20,7 @@ import { RefreshCw } from 'lucide-react'; import { ProtectedRoute } from '@/components/auth/ProtectedRoute' -import { apiClient } from '../lib/api-client' +import { apiClient } from '@/lib/api-client' interface AnalyticsData { overview: { @@ -399,4 +399,4 @@ function AnalyticsPageContent() { ); -} \ No newline at end of file +} diff --git a/frontend/src/app/api-keys/page.tsx b/frontend/src/app/api-keys/page.tsx index 7eda2ac..0fce068 100644 --- a/frontend/src/app/api-keys/page.tsx +++ b/frontend/src/app/api-keys/page.tsx @@ -1,6 +1,7 @@ "use client"; -import { useState, useEffect } from "react"; +import { useState, useEffect, Suspense } from "react"; +export const dynamic = 'force-dynamic' import { useSearchParams } from "next/navigation"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; @@ -36,7 +37,7 @@ import { Bot } from "lucide-react"; import { useToast } from "@/hooks/use-toast"; -import { apiClient } from "../lib/api-client"; +import { apiClient } from "@/lib/api-client"; interface ApiKey { id: string; @@ -93,7 +94,7 @@ const PERMISSION_OPTIONS = [ { value: "llm:embeddings", label: "LLM Embeddings" }, ]; -export default function ApiKeysPage() { +function ApiKeysPageContent() { const { toast } = useToast(); const searchParams = useSearchParams(); const [apiKeys, setApiKeys] = useState([]); @@ -905,4 +906,12 @@ export default function ApiKeysPage() { ); -} \ No newline at end of file +} + +export default function ApiKeysPage() { + return ( + Loading...}> + + + ); +} diff --git a/frontend/src/app/audit/page.tsx b/frontend/src/app/audit/page.tsx index d4b513d..7567a17 100644 --- a/frontend/src/app/audit/page.tsx +++ b/frontend/src/app/audit/page.tsx @@ -1,7 +1,7 @@ "use client"; import { useState, useEffect } from "react"; -import { downloadFile } from "../lib/file-download"; +import { downloadFile } from "@/lib/file-download"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; @@ -27,7 +27,7 @@ import { ChevronRight } from "lucide-react"; import { useToast } from "@/hooks/use-toast"; -import { apiClient } from "../lib/api-client"; +import { apiClient } from "@/lib/api-client"; import { config } from "@/lib/config"; interface AuditLog { @@ -544,4 +544,4 @@ export default function AuditPage() { ); -} \ No newline at end of file +} diff --git a/frontend/src/app/budgets/page.tsx b/frontend/src/app/budgets/page.tsx index 7e9a761..f06c521 100644 --- a/frontend/src/app/budgets/page.tsx +++ b/frontend/src/app/budgets/page.tsx @@ -34,7 +34,7 @@ import { Clock } from "lucide-react"; import { useToast } from "@/hooks/use-toast"; -import { apiClient } from "../lib/api-client"; +import { apiClient } from "@/lib/api-client"; interface Budget { id: string; @@ -608,4 +608,4 @@ export default function BudgetsPage() { ); -} \ No newline at end of file +} diff --git a/frontend/src/app/dashboard/page.tsx b/frontend/src/app/dashboard/page.tsx index d878c49..35a7db4 100644 --- a/frontend/src/app/dashboard/page.tsx +++ b/frontend/src/app/dashboard/page.tsx @@ -5,7 +5,7 @@ import { useState, useEffect } from "react" import { ProtectedRoute } from "@/components/auth/ProtectedRoute" import { useToast } from "@/hooks/use-toast" import { config } from "@/lib/config" -import { apiClient } from "../lib/api-client" +import { apiClient } from "@/lib/api-client" // Force dynamic rendering for authentication export const dynamic = 'force-dynamic' @@ -476,4 +476,4 @@ function DashboardContent() { ) -} \ No newline at end of file +} diff --git a/frontend/src/app/llm/page.tsx b/frontend/src/app/llm/page.tsx index 117b18a..70362c8 100644 --- a/frontend/src/app/llm/page.tsx +++ b/frontend/src/app/llm/page.tsx @@ -25,7 +25,7 @@ import { AlertTriangle } from 'lucide-react' import { useToast } from '@/hooks/use-toast' -import { apiClient } from '../lib/api-client' +import { apiClient } from '@/lib/api-client' import { ProtectedRoute } from '@/components/auth/ProtectedRoute' import { useRouter } from 'next/navigation' @@ -468,4 +468,4 @@ function LLMPageContent() { ) -} \ No newline at end of file +} diff --git a/frontend/src/app/prompt-templates/page.tsx b/frontend/src/app/prompt-templates/page.tsx index 3232aad..57f438d 100644 --- a/frontend/src/app/prompt-templates/page.tsx +++ b/frontend/src/app/prompt-templates/page.tsx @@ -29,7 +29,7 @@ import { } from '@/components/ui/alert-dialog' import { Edit3, RotateCcw, Loader2, Save, AlertTriangle, Plus, Sparkles } from 'lucide-react' import toast from 'react-hot-toast' -import { apiClient } from '../lib/api-client' +import { apiClient } from '@/lib/api-client' import { config } from '@/lib/config' import { useAuth } from '@/contexts/AuthContext' @@ -725,4 +725,4 @@ export default function PromptTemplatesPage() { )} ) -} \ No newline at end of file +} diff --git a/frontend/src/app/rag/page.tsx b/frontend/src/app/rag/page.tsx index 4eba5ef..d69732f 100644 --- a/frontend/src/app/rag/page.tsx +++ b/frontend/src/app/rag/page.tsx @@ -13,7 +13,7 @@ import { DocumentUpload } from "@/components/rag/document-upload" import { DocumentBrowser } from "@/components/rag/document-browser" import { useAuth } from "@/contexts/AuthContext" import { ProtectedRoute } from '@/components/auth/ProtectedRoute' -import { apiClient } from '../lib/api-client' +import { apiClient } from '@/lib/api-client' interface Collection { id: string @@ -237,4 +237,4 @@ function RAGPageContent() { ) -} \ No newline at end of file +} diff --git a/frontend/src/app/register/page.tsx b/frontend/src/app/register/page.tsx index 53ece3f..4054b9b 100644 --- a/frontend/src/app/register/page.tsx +++ b/frontend/src/app/register/page.tsx @@ -10,7 +10,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/com import { Alert, AlertDescription } from "@/components/ui/alert"; import { Checkbox } from "@/components/ui/checkbox"; import { useToast } from "@/hooks/use-toast"; -import { apiClient } from "../lib/api-client"; +import { apiClient } from "@/lib/api-client"; interface RegisterFormData { username: string; @@ -288,4 +288,4 @@ export default function RegisterPage() { ); -} \ No newline at end of file +} diff --git a/frontend/src/app/settings/page.tsx b/frontend/src/app/settings/page.tsx index c5cf425..9af3f19 100644 --- a/frontend/src/app/settings/page.tsx +++ b/frontend/src/app/settings/page.tsx @@ -31,7 +31,7 @@ import { Play } from "lucide-react"; import { useToast } from "@/hooks/use-toast"; -import { apiClient } from "../lib/api-client"; +import { apiClient } from "@/lib/api-client"; import { useModules, triggerModuleRefresh } from '@/contexts/ModulesContext'; import { Badge } from '@/components/ui/badge'; @@ -1115,4 +1115,4 @@ export default function SettingsPage() { ); -} \ No newline at end of file +} diff --git a/frontend/src/app/test-auth/page.tsx b/frontend/src/app/test-auth/page.tsx index 15935d8..94d316f 100644 --- a/frontend/src/app/test-auth/page.tsx +++ b/frontend/src/app/test-auth/page.tsx @@ -4,7 +4,7 @@ import { useAuth } from "@/contexts/AuthContext" import { Button } from "@/components/ui/button" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { useState } from "react" -import { apiClient } from "../lib/api-client" +import { apiClient } from "@/lib/api-client" import { tokenManager } from "@/lib/token-manager" export default function TestAuthPage() { @@ -136,4 +136,4 @@ Authenticated: ${tokenManager.isAuthenticated()} ) -} \ No newline at end of file +} From cbf2e3c738f9b59d8a542729108255f33b0c24d4 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Tue, 16 Sep 2025 08:49:25 +0200 Subject: [PATCH 12/43] prod build fix --- frontend/Dockerfile | 2 +- frontend/next.config.js | 43 +++++++++++++++++++++++++++++++++-------- frontend/package.json | 1 + 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 5c26a2e..9a58595 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -11,7 +11,7 @@ WORKDIR /app COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./ RUN \ if [ -f yarn.lock ]; then yarn --frozen-lockfile; \ - elif [ -f package-lock.json ]; then npm ci; \ + elif [ -f package-lock.json ]; then npm install && npm ci; \ elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \ else echo "Lockfile not found." && exit 1; \ fi diff --git a/frontend/next.config.js b/frontend/next.config.js index 32baf9a..1b8c82c 100644 --- a/frontend/next.config.js +++ b/frontend/next.config.js @@ -1,3 +1,10 @@ +const path = require('path'); +let TsconfigPathsPlugin; +try { + // Optional: only used if installed + TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); +} catch (_) {} + /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, @@ -11,17 +18,37 @@ const nextConfig = { }, // Enable standalone output for better Docker compatibility output: 'standalone', - webpack: (config, { isServer, dev }) => { - config.resolve.alias = { - ...config.resolve.alias, - '@': require('path').join(__dirname, 'src'), - }; - - // Optional: Add debug logging + webpack: (config, { dev }) => { + // Ensure resolve object exists + config.resolve = config.resolve || {}; + config.resolve.alias = config.resolve.alias || {}; + + // Hard-set robust alias for "@" => /src + config.resolve.alias['@'] = path.resolve(__dirname, 'src'); + + // Ensure common extensions are resolvable + const exts = config.resolve.extensions || []; + config.resolve.extensions = Array.from(new Set([...exts, '.ts', '.tsx', '.js', '.jsx'])); + + // Add tsconfig-aware resolver plugin if available + if (TsconfigPathsPlugin) { + const existing = config.resolve.plugins || []; + existing.push( + new TsconfigPathsPlugin({ + configFile: path.resolve(__dirname, 'tsconfig.json'), + extensions: config.resolve.extensions, + mainFields: ['browser', 'module', 'main'], + }) + ); + config.resolve.plugins = existing; + } + + // Optional: Add debug logging in development if (dev) { + // eslint-disable-next-line no-console console.log('Webpack alias config:', config.resolve.alias); } - + return config; }, env: { diff --git a/frontend/package.json b/frontend/package.json index 1c8ec8c..7bb3a0f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,6 +9,7 @@ "lint": "next lint" }, "dependencies": { + "tsconfig-paths-webpack-plugin": "^4.1.0", "@hookform/resolvers": "^3.3.2", "@radix-ui/react-alert-dialog": "^1.1.14", "@radix-ui/react-avatar": "^1.0.4", From 8841bbf13a7c42f3c13488a336b9df3311549e14 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Tue, 16 Sep 2025 09:11:23 +0200 Subject: [PATCH 13/43] simplify --- frontend/Dockerfile | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 9a58595..4823e4c 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -7,14 +7,10 @@ FROM base AS deps RUN apk add --no-cache libc6-compat WORKDIR /app -# Install dependencies based on the preferred package manager -COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./ -RUN \ - if [ -f yarn.lock ]; then yarn --frozen-lockfile; \ - elif [ -f package-lock.json ]; then npm install && npm ci; \ - elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \ - else echo "Lockfile not found." && exit 1; \ - fi +# Install dependencies with npm only +COPY package.json package-lock.json ./ +RUN npm install +RUN npm ci # Rebuild the source code only when needed FROM base AS builder @@ -26,13 +22,8 @@ COPY . . ENV NEXT_TELEMETRY_DISABLED=1 ENV NODE_ENV=production -# Build the application -RUN \ - if [ -f yarn.lock ]; then yarn build; \ - elif [ -f package-lock.json ]; then npm run build; \ - elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm build; \ - else echo "Lockfile not found." && exit 1; \ - fi +# Build the application using npm only +RUN npm run build # Production image, copy all the files and run next FROM base AS runner From c7d1251ad380d4c9c9eded414d9e4edf0835858a Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Tue, 16 Sep 2025 09:14:02 +0200 Subject: [PATCH 14/43] node version bump in container --- frontend/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 4823e4c..084b31f 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,5 +1,5 @@ # Use the official Node.js runtime as the base image -FROM node:18-alpine AS base +FROM node:22-alpine AS base # Install dependencies only when needed FROM base AS deps From e18a652d7ab0fdc4566078f2ad0ae7ce17fa2203 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Tue, 16 Sep 2025 10:54:41 +0200 Subject: [PATCH 15/43] prod build fixing --- frontend/Dockerfile | 2 + frontend/package-lock.json | 1807 +-------------------------- frontend/package.json | 1 - frontend/src/app/test-auth/page.tsx | 18 +- 4 files changed, 70 insertions(+), 1758 deletions(-) diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 084b31f..dce03e6 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -23,6 +23,8 @@ ENV NEXT_TELEMETRY_DISABLED=1 ENV NODE_ENV=production # Build the application using npm only +RUN npm install +RUN npm install autoprefixer RUN npm run build # Production image, copy all the files and run next diff --git a/frontend/package-lock.json b/frontend/package-lock.json index b5af4b6..2972dfa 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -48,6 +48,7 @@ "remark-gfm": "^4.0.1", "tailwind-merge": "^2.1.0", "tailwindcss-animate": "^1.0.7", + "tsconfig-paths-webpack-plugin": "^4.1.0", "zod": "^3.22.4" }, "devDependencies": { @@ -55,7 +56,6 @@ "@types/node": "^20.10.0", "@types/react": "^18.2.39", "@types/react-dom": "^18.2.17", - "autoprefixer": "^10.4.16", "eslint": "^8.54.0", "eslint-config-next": "14.0.4", "postcss": "^8.4.32", @@ -65,8 +65,6 @@ }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", "license": "MIT", "engines": { "node": ">=10" @@ -77,51 +75,13 @@ }, "node_modules/@babel/runtime": { "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.3.tgz", - "integrity": "sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, - "node_modules/@emnapi/core": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.5.tgz", - "integrity": "sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.0.4", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.5.tgz", - "integrity": "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.4.tgz", - "integrity": "sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", - "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", "dev": true, "license": "MIT", "dependencies": { @@ -139,8 +99,6 @@ }, "node_modules/@eslint-community/regexpp": { "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, "license": "MIT", "engines": { @@ -149,8 +107,6 @@ }, "node_modules/@eslint/eslintrc": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "license": "MIT", "dependencies": { @@ -173,8 +129,6 @@ }, "node_modules/@eslint/js": { "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "dev": true, "license": "MIT", "engines": { @@ -183,8 +137,6 @@ }, "node_modules/@floating-ui/core": { "version": "1.7.3", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", - "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", "license": "MIT", "dependencies": { "@floating-ui/utils": "^0.2.10" @@ -192,8 +144,6 @@ }, "node_modules/@floating-ui/dom": { "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", - "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", "license": "MIT", "dependencies": { "@floating-ui/core": "^1.7.3", @@ -202,8 +152,6 @@ }, "node_modules/@floating-ui/react-dom": { "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz", - "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==", "license": "MIT", "dependencies": { "@floating-ui/dom": "^1.7.4" @@ -215,14 +163,10 @@ }, "node_modules/@floating-ui/utils": { "version": "0.2.10", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", - "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", "license": "MIT" }, "node_modules/@hookform/resolvers": { "version": "3.10.0", - "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.10.0.tgz", - "integrity": "sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag==", "license": "MIT", "peerDependencies": { "react-hook-form": "^7.0.0" @@ -230,9 +174,6 @@ }, "node_modules/@humanwhocodes/config-array": { "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -246,8 +187,6 @@ }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -260,16 +199,11 @@ }, "node_modules/@humanwhocodes/object-schema": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@isaacs/cliui": { "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "license": "ISC", "dependencies": { "string-width": "^5.1.2", @@ -285,8 +219,6 @@ }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz", - "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==", "license": "MIT", "engines": { "node": ">=12" @@ -297,8 +229,6 @@ }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -312,8 +242,6 @@ }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", @@ -322,8 +250,6 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "license": "MIT", "engines": { "node": ">=6.0.0" @@ -331,117 +257,30 @@ }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.30", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz", - "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==", "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", - "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.10.0" - } - }, "node_modules/@next/env": { "version": "14.2.32", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.32.tgz", - "integrity": "sha512-n9mQdigI6iZ/DF6pCTwMKeWgF2e8lg7qgt5M7HXMLtyhZYMnf/u905M18sSpPmHL9MKp9JHo56C6jrD2EvWxng==", "license": "MIT" }, "node_modules/@next/eslint-plugin-next": { "version": "14.0.4", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.0.4.tgz", - "integrity": "sha512-U3qMNHmEZoVmHA0j/57nRfi3AscXNvkOnxDmle/69Jz/G0o/gWjXTDdlgILZdrxQ0Lw/jv2mPW8PGy0EGIHXhQ==", "dev": true, "license": "MIT", "dependencies": { "glob": "7.1.7" } }, - "node_modules/@next/swc-darwin-arm64": { - "version": "14.2.32", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.32.tgz", - "integrity": "sha512-osHXveM70zC+ilfuFa/2W6a1XQxJTvEhzEycnjUaVE8kpUS09lDpiDDX2YLdyFCzoUbvbo5r0X1Kp4MllIOShw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-darwin-x64": { - "version": "14.2.32", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.32.tgz", - "integrity": "sha512-P9NpCAJuOiaHHpqtrCNncjqtSBi1f6QUdHK/+dNabBIXB2RUFWL19TY1Hkhu74OvyNQEYEzzMJCMQk5agjw1Qg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.2.32", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.32.tgz", - "integrity": "sha512-v7JaO0oXXt6d+cFjrrKqYnR2ubrD+JYP7nQVRZgeo5uNE5hkCpWnHmXm9vy3g6foMO8SPwL0P3MPw1c+BjbAzA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.2.32", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.32.tgz", - "integrity": "sha512-tA6sIKShXtSJBTH88i0DRd6I9n3ZTirmwpwAqH5zdJoQF7/wlJXR8DkPmKwYl5mFWhEKr5IIa3LfpMW9RRwKmQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@next/swc-linux-x64-gnu": { "version": "14.2.32", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.32.tgz", - "integrity": "sha512-7S1GY4TdnlGVIdeXXKQdDkfDysoIVFMD0lJuVVMeb3eoVjrknQ0JNN7wFlhCvea0hEk0Sd4D1hedVChDKfV2jw==", "cpu": [ "x64" ], @@ -456,8 +295,6 @@ }, "node_modules/@next/swc-linux-x64-musl": { "version": "14.2.32", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.32.tgz", - "integrity": "sha512-OHHC81P4tirVa6Awk6eCQ6RBfWl8HpFsZtfEkMpJ5GjPsJ3nhPe6wKAJUZ/piC8sszUkAgv3fLflgzPStIwfWg==", "cpu": [ "x64" ], @@ -470,58 +307,8 @@ "node": ">= 10" } }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.2.32", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.32.tgz", - "integrity": "sha512-rORQjXsAFeX6TLYJrCG5yoIDj+NKq31Rqwn8Wpn/bkPNy5rTHvOXkW8mLFonItS7QC6M+1JIIcLe+vOCTOYpvg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.2.32", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.32.tgz", - "integrity": "sha512-jHUeDPVHrgFltqoAqDB6g6OStNnFxnc7Aks3p0KE0FbwAvRg6qWKYF5mSTdCTxA3axoSAUwxYdILzXJfUwlHhA==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.2.32", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.32.tgz", - "integrity": "sha512-2N0lSoU4GjfLSO50wvKpMQgKd4HdI2UHEhQPPPnlgfBJlOgJxkjpkYBqzk08f1gItBB6xF/n+ykso2hgxuydsA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -533,8 +320,6 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "license": "MIT", "engines": { "node": ">= 8" @@ -542,8 +327,6 @@ }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -555,8 +338,6 @@ }, "node_modules/@nolyfill/is-core-module": { "version": "1.0.39", - "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", - "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", "dev": true, "license": "MIT", "engines": { @@ -565,8 +346,6 @@ }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "license": "MIT", "optional": true, "engines": { @@ -575,20 +354,14 @@ }, "node_modules/@radix-ui/number": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", - "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", "license": "MIT" }, "node_modules/@radix-ui/primitive": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", - "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", "license": "MIT" }, "node_modules/@radix-ui/react-alert-dialog": { "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.15.tgz", - "integrity": "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", @@ -615,8 +388,6 @@ }, "node_modules/@radix-ui/react-arrow": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", - "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", "license": "MIT", "dependencies": { "@radix-ui/react-primitive": "2.1.3" @@ -638,8 +409,6 @@ }, "node_modules/@radix-ui/react-avatar": { "version": "1.1.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.10.tgz", - "integrity": "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==", "license": "MIT", "dependencies": { "@radix-ui/react-context": "1.1.2", @@ -665,8 +434,6 @@ }, "node_modules/@radix-ui/react-checkbox": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz", - "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", @@ -695,8 +462,6 @@ }, "node_modules/@radix-ui/react-collapsible": { "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz", - "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", @@ -725,8 +490,6 @@ }, "node_modules/@radix-ui/react-collection": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", - "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", @@ -751,8 +514,6 @@ }, "node_modules/@radix-ui/react-compose-refs": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", - "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -766,8 +527,6 @@ }, "node_modules/@radix-ui/react-context": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", - "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -781,8 +540,6 @@ }, "node_modules/@radix-ui/react-dialog": { "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz", - "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", @@ -817,8 +574,6 @@ }, "node_modules/@radix-ui/react-direction": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", - "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -832,8 +587,6 @@ }, "node_modules/@radix-ui/react-dismissable-layer": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", - "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", @@ -859,8 +612,6 @@ }, "node_modules/@radix-ui/react-dropdown-menu": { "version": "2.1.16", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.16.tgz", - "integrity": "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", @@ -888,8 +639,6 @@ }, "node_modules/@radix-ui/react-focus-guards": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", - "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -903,8 +652,6 @@ }, "node_modules/@radix-ui/react-focus-scope": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", - "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", @@ -928,8 +675,6 @@ }, "node_modules/@radix-ui/react-icons": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.2.tgz", - "integrity": "sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==", "license": "MIT", "peerDependencies": { "react": "^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc" @@ -937,8 +682,6 @@ }, "node_modules/@radix-ui/react-id": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", - "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", "license": "MIT", "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" @@ -955,8 +698,6 @@ }, "node_modules/@radix-ui/react-label": { "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.7.tgz", - "integrity": "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==", "license": "MIT", "dependencies": { "@radix-ui/react-primitive": "2.1.3" @@ -978,8 +719,6 @@ }, "node_modules/@radix-ui/react-menu": { "version": "2.1.16", - "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.16.tgz", - "integrity": "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", @@ -1018,8 +757,6 @@ }, "node_modules/@radix-ui/react-navigation-menu": { "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.14.tgz", - "integrity": "sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", @@ -1054,8 +791,6 @@ }, "node_modules/@radix-ui/react-popper": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", - "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==", "license": "MIT", "dependencies": { "@floating-ui/react-dom": "^2.0.0", @@ -1086,8 +821,6 @@ }, "node_modules/@radix-ui/react-portal": { "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", - "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", "license": "MIT", "dependencies": { "@radix-ui/react-primitive": "2.1.3", @@ -1110,8 +843,6 @@ }, "node_modules/@radix-ui/react-presence": { "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", - "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", @@ -1134,8 +865,6 @@ }, "node_modules/@radix-ui/react-primitive": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", - "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", "license": "MIT", "dependencies": { "@radix-ui/react-slot": "1.2.3" @@ -1157,8 +886,6 @@ }, "node_modules/@radix-ui/react-progress": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.7.tgz", - "integrity": "sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==", "license": "MIT", "dependencies": { "@radix-ui/react-context": "1.1.2", @@ -1181,8 +908,6 @@ }, "node_modules/@radix-ui/react-roving-focus": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", - "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", @@ -1212,8 +937,6 @@ }, "node_modules/@radix-ui/react-scroll-area": { "version": "1.2.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.10.tgz", - "integrity": "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==", "license": "MIT", "dependencies": { "@radix-ui/number": "1.1.1", @@ -1243,8 +966,6 @@ }, "node_modules/@radix-ui/react-select": { "version": "2.2.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz", - "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==", "license": "MIT", "dependencies": { "@radix-ui/number": "1.1.1", @@ -1286,8 +1007,6 @@ }, "node_modules/@radix-ui/react-separator": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz", - "integrity": "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==", "license": "MIT", "dependencies": { "@radix-ui/react-primitive": "2.1.3" @@ -1309,8 +1028,6 @@ }, "node_modules/@radix-ui/react-slider": { "version": "1.3.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.3.6.tgz", - "integrity": "sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==", "license": "MIT", "dependencies": { "@radix-ui/number": "1.1.1", @@ -1342,8 +1059,6 @@ }, "node_modules/@radix-ui/react-slot": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" @@ -1360,8 +1075,6 @@ }, "node_modules/@radix-ui/react-switch": { "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.6.tgz", - "integrity": "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", @@ -1389,8 +1102,6 @@ }, "node_modules/@radix-ui/react-tabs": { "version": "1.1.13", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz", - "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", @@ -1419,8 +1130,6 @@ }, "node_modules/@radix-ui/react-toast": { "version": "1.2.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.15.tgz", - "integrity": "sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", @@ -1453,8 +1162,6 @@ }, "node_modules/@radix-ui/react-tooltip": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz", - "integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", @@ -1487,8 +1194,6 @@ }, "node_modules/@radix-ui/react-use-callback-ref": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", - "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -1502,8 +1207,6 @@ }, "node_modules/@radix-ui/react-use-controllable-state": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", - "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", "license": "MIT", "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", @@ -1521,8 +1224,6 @@ }, "node_modules/@radix-ui/react-use-effect-event": { "version": "0.0.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", - "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", "license": "MIT", "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" @@ -1539,8 +1240,6 @@ }, "node_modules/@radix-ui/react-use-escape-keydown": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", - "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", "license": "MIT", "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" @@ -1557,8 +1256,6 @@ }, "node_modules/@radix-ui/react-use-is-hydrated": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.0.tgz", - "integrity": "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==", "license": "MIT", "dependencies": { "use-sync-external-store": "^1.5.0" @@ -1575,8 +1272,6 @@ }, "node_modules/@radix-ui/react-use-layout-effect": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", - "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -1590,8 +1285,6 @@ }, "node_modules/@radix-ui/react-use-previous": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", - "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -1605,8 +1298,6 @@ }, "node_modules/@radix-ui/react-use-rect": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", - "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", "license": "MIT", "dependencies": { "@radix-ui/rect": "1.1.1" @@ -1623,8 +1314,6 @@ }, "node_modules/@radix-ui/react-use-size": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", - "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", "license": "MIT", "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" @@ -1641,8 +1330,6 @@ }, "node_modules/@radix-ui/react-visually-hidden": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", - "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", "license": "MIT", "dependencies": { "@radix-ui/react-primitive": "2.1.3" @@ -1664,34 +1351,24 @@ }, "node_modules/@radix-ui/rect": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", - "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", "license": "MIT" }, "node_modules/@rtsao/scc": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", - "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", "dev": true, "license": "MIT" }, "node_modules/@rushstack/eslint-patch": { "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.12.0.tgz", - "integrity": "sha512-5EwMtOqvJMMa3HbmxLlF74e+3/HhwBTMcvt3nqVJgGCozO6hzIPOBlwm8mGVNR9SN2IJpxSnlxczyDjcn7qIyw==", "dev": true, "license": "MIT" }, "node_modules/@swc/counter": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", - "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", "license": "Apache-2.0" }, "node_modules/@swc/helpers": { "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", - "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3", @@ -1700,8 +1377,6 @@ }, "node_modules/@tailwindcss/typography": { "version": "0.5.16", - "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz", - "integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==", "license": "MIT", "dependencies": { "lodash.castarray": "^4.4.0", @@ -1713,21 +1388,8 @@ "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" } }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.0.tgz", - "integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@types/debug": { "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", "license": "MIT", "dependencies": { "@types/ms": "*" @@ -1735,14 +1397,10 @@ }, "node_modules/@types/estree": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "license": "MIT" }, "node_modules/@types/estree-jsx": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", - "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", "license": "MIT", "dependencies": { "@types/estree": "*" @@ -1750,8 +1408,6 @@ }, "node_modules/@types/hast": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", "license": "MIT", "dependencies": { "@types/unist": "*" @@ -1759,22 +1415,16 @@ }, "node_modules/@types/js-cookie": { "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.6.tgz", - "integrity": "sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==", "dev": true, "license": "MIT" }, "node_modules/@types/json5": { "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true, "license": "MIT" }, "node_modules/@types/mdast": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", "license": "MIT", "dependencies": { "@types/unist": "*" @@ -1782,14 +1432,10 @@ }, "node_modules/@types/ms": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", "license": "MIT" }, "node_modules/@types/node": { "version": "20.19.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.11.tgz", - "integrity": "sha512-uug3FEEGv0r+jrecvUUpbY8lLisvIjg6AAic6a2bSP5OEOLeJsDSnvhCDov7ipFFMXS3orMpzlmi0ZcuGkBbow==", "dev": true, "license": "MIT", "dependencies": { @@ -1798,14 +1444,10 @@ }, "node_modules/@types/prop-types": { "version": "15.7.15", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", - "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", "license": "MIT" }, "node_modules/@types/react": { "version": "18.3.24", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.24.tgz", - "integrity": "sha512-0dLEBsA1kI3OezMBF8nSsb7Nk19ZnsyE1LLhB8r27KbgU5H4pvuqZLdtE+aUkJVoXgTVuA+iLIwmZ0TuK4tx6A==", "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -1814,8 +1456,6 @@ }, "node_modules/@types/react-dom": { "version": "18.3.7", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", - "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", "devOptional": true, "license": "MIT", "peerDependencies": { @@ -1824,14 +1464,10 @@ }, "node_modules/@types/unist": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", "license": "MIT" }, "node_modules/@typescript-eslint/parser": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", - "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -1859,8 +1495,6 @@ }, "node_modules/@typescript-eslint/scope-manager": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, "license": "MIT", "dependencies": { @@ -1877,8 +1511,6 @@ }, "node_modules/@typescript-eslint/types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true, "license": "MIT", "engines": { @@ -1891,8 +1523,6 @@ }, "node_modules/@typescript-eslint/typescript-estree": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -1920,8 +1550,6 @@ }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1930,8 +1558,6 @@ }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, "license": "ISC", "dependencies": { @@ -1946,8 +1572,6 @@ }, "node_modules/@typescript-eslint/visitor-keys": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, "license": "MIT", "dependencies": { @@ -1964,196 +1588,10 @@ }, "node_modules/@ungap/structured-clone": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", "license": "ISC" }, - "node_modules/@unrs/resolver-binding-android-arm-eabi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", - "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-android-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", - "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", - "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", - "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", - "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", - "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", - "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", - "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", - "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", - "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", - "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", - "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", - "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, "node_modules/@unrs/resolver-binding-linux-x64-gnu": { "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", - "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", "cpu": [ "x64" ], @@ -2166,8 +1604,6 @@ }, "node_modules/@unrs/resolver-binding-linux-x64-musl": { "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", - "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", "cpu": [ "x64" ], @@ -2178,69 +1614,8 @@ "linux" ] }, - "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", - "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^0.2.11" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", - "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", - "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", - "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/acorn": { "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", "bin": { @@ -2252,8 +1627,6 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "license": "MIT", "peerDependencies": { @@ -2262,8 +1635,6 @@ }, "node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", "dependencies": { @@ -2279,8 +1650,6 @@ }, "node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "license": "MIT", "engines": { "node": ">=8" @@ -2288,8 +1657,6 @@ }, "node_modules/ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -2303,14 +1670,10 @@ }, "node_modules/any-promise": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", "license": "MIT" }, "node_modules/anymatch": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", @@ -2322,21 +1685,15 @@ }, "node_modules/arg": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", "license": "MIT" }, "node_modules/argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, "license": "Python-2.0" }, "node_modules/aria-hidden": { "version": "1.2.6", - "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", - "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", "license": "MIT", "dependencies": { "tslib": "^2.0.0" @@ -2347,8 +1704,6 @@ }, "node_modules/aria-query": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", "dev": true, "license": "Apache-2.0", "engines": { @@ -2357,8 +1712,6 @@ }, "node_modules/array-buffer-byte-length": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", - "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "dev": true, "license": "MIT", "dependencies": { @@ -2374,8 +1727,6 @@ }, "node_modules/array-includes": { "version": "3.1.9", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", - "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2397,8 +1748,6 @@ }, "node_modules/array-union": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, "license": "MIT", "engines": { @@ -2407,8 +1756,6 @@ }, "node_modules/array.prototype.findlast": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", - "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2428,8 +1775,6 @@ }, "node_modules/array.prototype.findlastindex": { "version": "1.2.6", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", - "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2450,8 +1795,6 @@ }, "node_modules/array.prototype.flat": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", - "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", "dev": true, "license": "MIT", "dependencies": { @@ -2469,8 +1812,6 @@ }, "node_modules/array.prototype.flatmap": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", - "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", "dev": true, "license": "MIT", "dependencies": { @@ -2488,8 +1829,6 @@ }, "node_modules/array.prototype.tosorted": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", - "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", "dev": true, "license": "MIT", "dependencies": { @@ -2505,8 +1844,6 @@ }, "node_modules/arraybuffer.prototype.slice": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", - "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2527,15 +1864,11 @@ }, "node_modules/ast-types-flow": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", - "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", "dev": true, "license": "MIT" }, "node_modules/async-function": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", - "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", "dev": true, "license": "MIT", "engines": { @@ -2544,52 +1877,10 @@ }, "node_modules/asynckit": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, - "node_modules/autoprefixer": { - "version": "10.4.21", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", - "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "browserslist": "^4.24.4", - "caniuse-lite": "^1.0.30001702", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.1.1", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, "node_modules/available-typed-arrays": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2604,8 +1895,6 @@ }, "node_modules/axe-core": { "version": "4.10.3", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz", - "integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==", "dev": true, "license": "MPL-2.0", "engines": { @@ -2614,8 +1903,6 @@ }, "node_modules/axios": { "version": "1.12.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", - "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", @@ -2625,8 +1912,6 @@ }, "node_modules/axobject-query": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", - "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -2635,8 +1920,6 @@ }, "node_modules/bail": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", "license": "MIT", "funding": { "type": "github", @@ -2645,14 +1928,10 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, "node_modules/big-integer": { "version": "1.6.52", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", - "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", "license": "Unlicense", "engines": { "node": ">=0.6" @@ -2660,8 +1939,6 @@ }, "node_modules/binary-extensions": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "license": "MIT", "engines": { "node": ">=8" @@ -2672,8 +1949,6 @@ }, "node_modules/brace-expansion": { "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -2682,8 +1957,6 @@ }, "node_modules/braces": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -2694,8 +1967,6 @@ }, "node_modules/broadcast-channel": { "version": "3.7.0", - "resolved": "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.7.0.tgz", - "integrity": "sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.7.2", @@ -2708,43 +1979,8 @@ "unload": "2.2.0" } }, - "node_modules/browserslist": { - "version": "4.25.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.3.tgz", - "integrity": "sha512-cDGv1kkDI4/0e5yON9yM5G/0A5u8sf5TnmdX5C9qHzI9PPu++sQ9zjm1k9NiOrf3riY4OkK0zSGqfvJyJsgCBQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001735", - "electron-to-chromium": "^1.5.204", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.3" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, "node_modules/busboy": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", "dependencies": { "streamsearch": "^1.1.0" }, @@ -2754,8 +1990,6 @@ }, "node_modules/call-bind": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, "license": "MIT", "dependencies": { @@ -2773,8 +2007,6 @@ }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -2786,8 +2018,6 @@ }, "node_modules/call-bound": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "dev": true, "license": "MIT", "dependencies": { @@ -2803,8 +2033,6 @@ }, "node_modules/callsites": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "license": "MIT", "engines": { @@ -2813,8 +2041,6 @@ }, "node_modules/camelcase-css": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", "license": "MIT", "engines": { "node": ">= 6" @@ -2822,8 +2048,6 @@ }, "node_modules/caniuse-lite": { "version": "1.0.30001737", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001737.tgz", - "integrity": "sha512-BiloLiXtQNrY5UyF0+1nSJLXUENuhka2pzy2Fx5pGxqavdrxSCW4U6Pn/PoG3Efspi2frRbHpBV2XsrPE6EDlw==", "funding": [ { "type": "opencollective", @@ -2842,8 +2066,6 @@ }, "node_modules/ccount": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", "license": "MIT", "funding": { "type": "github", @@ -2852,9 +2074,6 @@ }, "node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -2869,8 +2088,6 @@ }, "node_modules/character-entities": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", "license": "MIT", "funding": { "type": "github", @@ -2879,8 +2096,6 @@ }, "node_modules/character-entities-html4": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", "license": "MIT", "funding": { "type": "github", @@ -2889,8 +2104,6 @@ }, "node_modules/character-entities-legacy": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", "license": "MIT", "funding": { "type": "github", @@ -2899,8 +2112,6 @@ }, "node_modules/character-reference-invalid": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", "license": "MIT", "funding": { "type": "github", @@ -2909,8 +2120,6 @@ }, "node_modules/chokidar": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "license": "MIT", "dependencies": { "anymatch": "~3.1.2", @@ -2933,8 +2142,6 @@ }, "node_modules/chokidar/node_modules/glob-parent": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -2945,8 +2152,6 @@ }, "node_modules/class-variance-authority": { "version": "0.7.1", - "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", - "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", "license": "Apache-2.0", "dependencies": { "clsx": "^2.1.1" @@ -2957,14 +2162,10 @@ }, "node_modules/client-only": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", "license": "MIT" }, "node_modules/clsx": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "license": "MIT", "engines": { "node": ">=6" @@ -2972,8 +2173,6 @@ }, "node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -2984,14 +2183,10 @@ }, "node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" @@ -3002,8 +2197,6 @@ }, "node_modules/comma-separated-tokens": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", "license": "MIT", "funding": { "type": "github", @@ -3012,8 +2205,6 @@ }, "node_modules/commander": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "license": "MIT", "engines": { "node": ">= 6" @@ -3021,14 +2212,10 @@ }, "node_modules/concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "license": "MIT" }, "node_modules/cross-spawn": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -3041,8 +2228,6 @@ }, "node_modules/cssesc": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "license": "MIT", "bin": { "cssesc": "bin/cssesc" @@ -3053,21 +2238,15 @@ }, "node_modules/csstype": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "license": "MIT" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", "dev": true, "license": "BSD-2-Clause" }, "node_modules/data-view-buffer": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", - "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3084,8 +2263,6 @@ }, "node_modules/data-view-byte-length": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", - "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3102,8 +2279,6 @@ }, "node_modules/data-view-byte-offset": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", - "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3120,8 +2295,6 @@ }, "node_modules/date-fns": { "version": "2.30.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", - "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.21.0" @@ -3136,8 +2309,6 @@ }, "node_modules/debug": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -3153,8 +2324,6 @@ }, "node_modules/decode-named-character-reference": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", - "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", "license": "MIT", "dependencies": { "character-entities": "^2.0.0" @@ -3166,15 +2335,11 @@ }, "node_modules/deep-is": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true, "license": "MIT" }, "node_modules/define-data-property": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "license": "MIT", "dependencies": { @@ -3191,8 +2356,6 @@ }, "node_modules/define-properties": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, "license": "MIT", "dependencies": { @@ -3209,8 +2372,6 @@ }, "node_modules/delayed-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "license": "MIT", "engines": { "node": ">=0.4.0" @@ -3218,8 +2379,6 @@ }, "node_modules/dequal": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "license": "MIT", "engines": { "node": ">=6" @@ -3227,20 +2386,14 @@ }, "node_modules/detect-node": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "license": "MIT" }, "node_modules/detect-node-es": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", - "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", "license": "MIT" }, "node_modules/devlop": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", "license": "MIT", "dependencies": { "dequal": "^2.0.0" @@ -3252,14 +2405,10 @@ }, "node_modules/didyoumean": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", "license": "Apache-2.0" }, "node_modules/dir-glob": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "license": "MIT", "dependencies": { @@ -3271,14 +2420,10 @@ }, "node_modules/dlv": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", "license": "MIT" }, "node_modules/doctrine": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3290,8 +2435,6 @@ }, "node_modules/dunder-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -3304,27 +2447,25 @@ }, "node_modules/eastasianwidth": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "license": "MIT" }, - "node_modules/electron-to-chromium": { - "version": "1.5.208", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.208.tgz", - "integrity": "sha512-ozZyibehoe7tOhNaf16lKmljVf+3npZcJIEbJRVftVsmAg5TeA1mGS9dVCZzOwr2xT7xK15V0p7+GZqSPgkuPg==", - "dev": true, - "license": "ISC" - }, "node_modules/emoji-regex": { "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "license": "MIT" }, + "node_modules/enhanced-resolve": { + "version": "5.18.3", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/es-abstract": { "version": "1.24.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", - "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", "dev": true, "license": "MIT", "dependencies": { @@ -3392,8 +2533,6 @@ }, "node_modules/es-define-property": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -3401,8 +2540,6 @@ }, "node_modules/es-errors": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -3410,8 +2547,6 @@ }, "node_modules/es-iterator-helpers": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", - "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", "dev": true, "license": "MIT", "dependencies": { @@ -3438,8 +2573,6 @@ }, "node_modules/es-object-atoms": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -3450,8 +2583,6 @@ }, "node_modules/es-set-tostringtag": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -3465,8 +2596,6 @@ }, "node_modules/es-shim-unscopables": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", - "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", "dev": true, "license": "MIT", "dependencies": { @@ -3478,8 +2607,6 @@ }, "node_modules/es-to-primitive": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", - "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "dev": true, "license": "MIT", "dependencies": { @@ -3494,20 +2621,8 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/escape-string-regexp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "license": "MIT", "engines": { @@ -3519,9 +2634,6 @@ }, "node_modules/eslint": { "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", "dependencies": { @@ -3576,8 +2688,6 @@ }, "node_modules/eslint-config-next": { "version": "14.0.4", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.0.4.tgz", - "integrity": "sha512-9/xbOHEQOmQtqvQ1UsTQZpnA7SlDMBtuKJ//S4JnoyK3oGLhILKXdBgu/UO7lQo/2xOykQULS1qQ6p2+EpHgAQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3603,8 +2713,6 @@ }, "node_modules/eslint-import-resolver-node": { "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, "license": "MIT", "dependencies": { @@ -3615,8 +2723,6 @@ }, "node_modules/eslint-import-resolver-node/node_modules/debug": { "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3625,8 +2731,6 @@ }, "node_modules/eslint-import-resolver-typescript": { "version": "3.10.1", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz", - "integrity": "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==", "dev": true, "license": "ISC", "dependencies": { @@ -3660,8 +2764,6 @@ }, "node_modules/eslint-module-utils": { "version": "2.12.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", - "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", "dev": true, "license": "MIT", "dependencies": { @@ -3678,8 +2780,6 @@ }, "node_modules/eslint-module-utils/node_modules/debug": { "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3688,8 +2788,6 @@ }, "node_modules/eslint-plugin-import": { "version": "2.32.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", - "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", "dependencies": { @@ -3722,8 +2820,6 @@ }, "node_modules/eslint-plugin-import/node_modules/debug": { "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3732,8 +2828,6 @@ }, "node_modules/eslint-plugin-import/node_modules/doctrine": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3745,8 +2839,6 @@ }, "node_modules/eslint-plugin-import/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", "bin": { @@ -3755,8 +2847,6 @@ }, "node_modules/eslint-plugin-jsx-a11y": { "version": "6.10.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", - "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", "dev": true, "license": "MIT", "dependencies": { @@ -3785,8 +2875,6 @@ }, "node_modules/eslint-plugin-react": { "version": "7.37.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", - "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", "dev": true, "license": "MIT", "dependencies": { @@ -3818,8 +2906,6 @@ }, "node_modules/eslint-plugin-react-hooks": { "version": "5.0.0-canary-7118f5dd7-20230705", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0-canary-7118f5dd7-20230705.tgz", - "integrity": "sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw==", "dev": true, "license": "MIT", "engines": { @@ -3831,8 +2917,6 @@ }, "node_modules/eslint-plugin-react/node_modules/doctrine": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3844,8 +2928,6 @@ }, "node_modules/eslint-plugin-react/node_modules/resolve": { "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", "dev": true, "license": "MIT", "dependencies": { @@ -3862,8 +2944,6 @@ }, "node_modules/eslint-plugin-react/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", "bin": { @@ -3872,8 +2952,6 @@ }, "node_modules/eslint-scope": { "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -3889,8 +2967,6 @@ }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "license": "Apache-2.0", "engines": { @@ -3902,8 +2978,6 @@ }, "node_modules/espree": { "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -3920,8 +2994,6 @@ }, "node_modules/esquery": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -3933,8 +3005,6 @@ }, "node_modules/esrecurse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -3946,8 +3016,6 @@ }, "node_modules/estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -3956,8 +3024,6 @@ }, "node_modules/estree-util-is-identifier-name": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", - "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", "license": "MIT", "funding": { "type": "opencollective", @@ -3966,8 +3032,6 @@ }, "node_modules/esutils": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -3976,8 +3040,6 @@ }, "node_modules/events": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "license": "MIT", "engines": { "node": ">=0.8.x" @@ -3985,21 +3047,15 @@ }, "node_modules/extend": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true, "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -4014,8 +3070,6 @@ }, "node_modules/fast-glob/node_modules/glob-parent": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -4026,22 +3080,16 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true, "license": "MIT" }, "node_modules/fastq": { "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -4049,8 +3097,6 @@ }, "node_modules/file-entry-cache": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "license": "MIT", "dependencies": { @@ -4062,8 +3108,6 @@ }, "node_modules/fill-range": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -4074,8 +3118,6 @@ }, "node_modules/find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", "dependencies": { @@ -4091,8 +3133,6 @@ }, "node_modules/flat-cache": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "license": "MIT", "dependencies": { @@ -4106,15 +3146,11 @@ }, "node_modules/flatted": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "dev": true, "license": "ISC" }, "node_modules/follow-redirects": { "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "funding": [ { "type": "individual", @@ -4133,8 +3169,6 @@ }, "node_modules/for-each": { "version": "0.3.5", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", - "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, "license": "MIT", "dependencies": { @@ -4149,8 +3183,6 @@ }, "node_modules/foreground-child": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "license": "ISC", "dependencies": { "cross-spawn": "^7.0.6", @@ -4165,8 +3197,6 @@ }, "node_modules/form-data": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -4179,44 +3209,12 @@ "node": ">= 6" } }, - "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "license": "ISC" }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4224,8 +3222,6 @@ }, "node_modules/function.prototype.name": { "version": "1.1.8", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", - "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "dev": true, "license": "MIT", "dependencies": { @@ -4245,8 +3241,6 @@ }, "node_modules/functions-have-names": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, "license": "MIT", "funding": { @@ -4255,8 +3249,6 @@ }, "node_modules/get-intrinsic": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -4279,8 +3271,6 @@ }, "node_modules/get-nonce": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", - "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", "license": "MIT", "engines": { "node": ">=6" @@ -4288,8 +3278,6 @@ }, "node_modules/get-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -4301,8 +3289,6 @@ }, "node_modules/get-symbol-description": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", - "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "dev": true, "license": "MIT", "dependencies": { @@ -4319,8 +3305,6 @@ }, "node_modules/get-tsconfig": { "version": "4.10.1", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", - "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4332,9 +3316,6 @@ }, "node_modules/glob": { "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -4353,8 +3334,6 @@ }, "node_modules/glob-parent": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "license": "ISC", "dependencies": { "is-glob": "^4.0.3" @@ -4365,8 +3344,6 @@ }, "node_modules/globals": { "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4381,8 +3358,6 @@ }, "node_modules/globalthis": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4398,8 +3373,6 @@ }, "node_modules/globby": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "license": "MIT", "dependencies": { @@ -4419,8 +3392,6 @@ }, "node_modules/goober": { "version": "2.1.16", - "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.16.tgz", - "integrity": "sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==", "license": "MIT", "peerDependencies": { "csstype": "^3.0.10" @@ -4428,8 +3399,6 @@ }, "node_modules/gopd": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -4440,21 +3409,15 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, "node_modules/graphemer": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true, "license": "MIT" }, "node_modules/has-bigints": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", - "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", "dev": true, "license": "MIT", "engines": { @@ -4466,9 +3429,6 @@ }, "node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -4476,8 +3436,6 @@ }, "node_modules/has-property-descriptors": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "license": "MIT", "dependencies": { @@ -4489,8 +3447,6 @@ }, "node_modules/has-proto": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", - "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4505,8 +3461,6 @@ }, "node_modules/has-symbols": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -4517,8 +3471,6 @@ }, "node_modules/has-tostringtag": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -4532,8 +3484,6 @@ }, "node_modules/hasown": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -4544,8 +3494,6 @@ }, "node_modules/hast-util-is-element": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", - "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0" @@ -4557,8 +3505,6 @@ }, "node_modules/hast-util-to-jsx-runtime": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", - "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -4584,8 +3530,6 @@ }, "node_modules/hast-util-to-text": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", - "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -4600,8 +3544,6 @@ }, "node_modules/hast-util-whitespace": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0" @@ -4613,8 +3555,6 @@ }, "node_modules/highlight.js": { "version": "11.11.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", - "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", "license": "BSD-3-Clause", "engines": { "node": ">=12.0.0" @@ -4622,8 +3562,6 @@ }, "node_modules/html-url-attributes": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz", - "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==", "license": "MIT", "funding": { "type": "opencollective", @@ -4632,8 +3570,6 @@ }, "node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { @@ -4642,8 +3578,6 @@ }, "node_modules/import-fresh": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4659,8 +3593,6 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "license": "MIT", "engines": { @@ -4669,9 +3601,6 @@ }, "node_modules/inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -4680,20 +3609,14 @@ }, "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, "node_modules/inline-style-parser": { "version": "0.2.4", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", - "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==", "license": "MIT" }, "node_modules/internal-slot": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", - "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "dev": true, "license": "MIT", "dependencies": { @@ -4707,8 +3630,6 @@ }, "node_modules/is-alphabetical": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", "license": "MIT", "funding": { "type": "github", @@ -4717,8 +3638,6 @@ }, "node_modules/is-alphanumerical": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", "license": "MIT", "dependencies": { "is-alphabetical": "^2.0.0", @@ -4731,8 +3650,6 @@ }, "node_modules/is-array-buffer": { "version": "3.0.5", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", - "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "dev": true, "license": "MIT", "dependencies": { @@ -4749,8 +3666,6 @@ }, "node_modules/is-async-function": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", - "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4769,8 +3684,6 @@ }, "node_modules/is-bigint": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", - "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4785,8 +3698,6 @@ }, "node_modules/is-binary-path": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" @@ -4797,8 +3708,6 @@ }, "node_modules/is-boolean-object": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", - "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", "dev": true, "license": "MIT", "dependencies": { @@ -4814,8 +3723,6 @@ }, "node_modules/is-bun-module": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", - "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4824,8 +3731,6 @@ }, "node_modules/is-callable": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, "license": "MIT", "engines": { @@ -4837,8 +3742,6 @@ }, "node_modules/is-core-module": { "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -4852,8 +3755,6 @@ }, "node_modules/is-data-view": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", - "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", "dev": true, "license": "MIT", "dependencies": { @@ -4870,8 +3771,6 @@ }, "node_modules/is-date-object": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", - "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", "dev": true, "license": "MIT", "dependencies": { @@ -4887,8 +3786,6 @@ }, "node_modules/is-decimal": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", "license": "MIT", "funding": { "type": "github", @@ -4897,8 +3794,6 @@ }, "node_modules/is-extglob": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -4906,8 +3801,6 @@ }, "node_modules/is-finalizationregistry": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", - "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", "dev": true, "license": "MIT", "dependencies": { @@ -4922,8 +3815,6 @@ }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "license": "MIT", "engines": { "node": ">=8" @@ -4931,8 +3822,6 @@ }, "node_modules/is-generator-function": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", - "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4950,8 +3839,6 @@ }, "node_modules/is-glob": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -4962,8 +3849,6 @@ }, "node_modules/is-hexadecimal": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", "license": "MIT", "funding": { "type": "github", @@ -4972,8 +3857,6 @@ }, "node_modules/is-map": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true, "license": "MIT", "engines": { @@ -4985,8 +3868,6 @@ }, "node_modules/is-negative-zero": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "license": "MIT", "engines": { @@ -4998,8 +3879,6 @@ }, "node_modules/is-number": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "license": "MIT", "engines": { "node": ">=0.12.0" @@ -5007,8 +3886,6 @@ }, "node_modules/is-number-object": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", - "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "dev": true, "license": "MIT", "dependencies": { @@ -5024,8 +3901,6 @@ }, "node_modules/is-path-inside": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, "license": "MIT", "engines": { @@ -5034,8 +3909,6 @@ }, "node_modules/is-plain-obj": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "license": "MIT", "engines": { "node": ">=12" @@ -5046,8 +3919,6 @@ }, "node_modules/is-regex": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", - "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "dev": true, "license": "MIT", "dependencies": { @@ -5065,8 +3936,6 @@ }, "node_modules/is-set": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", - "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", "dev": true, "license": "MIT", "engines": { @@ -5078,8 +3947,6 @@ }, "node_modules/is-shared-array-buffer": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", - "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", "dev": true, "license": "MIT", "dependencies": { @@ -5094,8 +3961,6 @@ }, "node_modules/is-string": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", - "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "dev": true, "license": "MIT", "dependencies": { @@ -5111,8 +3976,6 @@ }, "node_modules/is-symbol": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", - "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", "dev": true, "license": "MIT", "dependencies": { @@ -5129,8 +3992,6 @@ }, "node_modules/is-typed-array": { "version": "1.1.15", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", - "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5145,8 +4006,6 @@ }, "node_modules/is-weakmap": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", - "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", "dev": true, "license": "MIT", "engines": { @@ -5158,8 +4017,6 @@ }, "node_modules/is-weakref": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", - "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", "dev": true, "license": "MIT", "dependencies": { @@ -5174,8 +4031,6 @@ }, "node_modules/is-weakset": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", - "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5191,21 +4046,15 @@ }, "node_modules/isarray": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true, "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "license": "ISC" }, "node_modules/iterator.prototype": { "version": "1.1.5", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", - "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", "dev": true, "license": "MIT", "dependencies": { @@ -5222,8 +4071,6 @@ }, "node_modules/jackspeak": { "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -5237,8 +4084,6 @@ }, "node_modules/jiti": { "version": "1.21.7", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", - "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "license": "MIT", "bin": { "jiti": "bin/jiti.js" @@ -5246,8 +4091,6 @@ }, "node_modules/js-cookie": { "version": "3.0.5", - "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", - "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", "license": "MIT", "engines": { "node": ">=14" @@ -5255,20 +4098,14 @@ }, "node_modules/js-sha3": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", "license": "MIT" }, "node_modules/js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "license": "MIT", "dependencies": { @@ -5280,29 +4117,21 @@ }, "node_modules/json-buffer": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true, "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true, "license": "MIT" }, "node_modules/json5": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "license": "MIT", "dependencies": { @@ -5314,8 +4143,6 @@ }, "node_modules/jsx-ast-utils": { "version": "3.3.5", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", - "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5330,8 +4157,6 @@ }, "node_modules/keyv": { "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "license": "MIT", "dependencies": { @@ -5340,15 +4165,11 @@ }, "node_modules/language-subtag-registry": { "version": "0.3.23", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", - "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", "dev": true, "license": "CC0-1.0" }, "node_modules/language-tags": { "version": "1.0.9", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", - "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", "dev": true, "license": "MIT", "dependencies": { @@ -5360,8 +4181,6 @@ }, "node_modules/levn": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5374,8 +4193,6 @@ }, "node_modules/lilconfig": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", - "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "license": "MIT", "engines": { "node": ">=14" @@ -5386,14 +4203,10 @@ }, "node_modules/lines-and-columns": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "license": "MIT" }, "node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", "dependencies": { @@ -5408,26 +4221,18 @@ }, "node_modules/lodash.castarray": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", - "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==", "license": "MIT" }, "node_modules/lodash.isplainobject": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "license": "MIT" }, "node_modules/longest-streak": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", "license": "MIT", "funding": { "type": "github", @@ -5436,8 +4241,6 @@ }, "node_modules/loose-envify": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" @@ -5448,8 +4251,6 @@ }, "node_modules/lowlight": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-3.3.0.tgz", - "integrity": "sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -5463,14 +4264,10 @@ }, "node_modules/lru-cache": { "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "license": "ISC" }, "node_modules/lucide-react": { "version": "0.294.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.294.0.tgz", - "integrity": "sha512-V7o0/VECSGbLHn3/1O67FUgBwWB+hmzshrgDVRJQhMh8uj5D3HBuIvhuAmQTtlupILSplwIZg5FTc4tTKMA2SA==", "license": "ISC", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0" @@ -5478,8 +4275,6 @@ }, "node_modules/markdown-table": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", - "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", "license": "MIT", "funding": { "type": "github", @@ -5488,8 +4283,6 @@ }, "node_modules/match-sorter": { "version": "6.3.4", - "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.4.tgz", - "integrity": "sha512-jfZW7cWS5y/1xswZo8VBOdudUiSd9nifYRWphc9M5D/ee4w4AoXLgBEdRbgVaxbMuagBPeUC5y2Hi8DO6o9aDg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.23.8", @@ -5498,8 +4291,6 @@ }, "node_modules/math-intrinsics": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -5507,8 +4298,6 @@ }, "node_modules/mdast-util-find-and-replace": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", - "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -5523,8 +4312,6 @@ }, "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "license": "MIT", "engines": { "node": ">=12" @@ -5535,8 +4322,6 @@ }, "node_modules/mdast-util-from-markdown": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", - "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -5559,8 +4344,6 @@ }, "node_modules/mdast-util-gfm": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", - "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", "license": "MIT", "dependencies": { "mdast-util-from-markdown": "^2.0.0", @@ -5578,8 +4361,6 @@ }, "node_modules/mdast-util-gfm-autolink-literal": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", - "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -5595,8 +4376,6 @@ }, "node_modules/mdast-util-gfm-footnote": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -5612,8 +4391,6 @@ }, "node_modules/mdast-util-gfm-strikethrough": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -5627,8 +4404,6 @@ }, "node_modules/mdast-util-gfm-table": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -5644,8 +4419,6 @@ }, "node_modules/mdast-util-gfm-task-list-item": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -5660,8 +4433,6 @@ }, "node_modules/mdast-util-mdx-expression": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", - "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -5678,8 +4449,6 @@ }, "node_modules/mdast-util-mdx-jsx": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", - "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -5702,8 +4471,6 @@ }, "node_modules/mdast-util-mdxjs-esm": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", - "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -5720,8 +4487,6 @@ }, "node_modules/mdast-util-phrasing": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", - "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -5734,8 +4499,6 @@ }, "node_modules/mdast-util-to-hast": { "version": "13.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", - "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -5755,8 +4518,6 @@ }, "node_modules/mdast-util-to-markdown": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", - "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -5776,8 +4537,6 @@ }, "node_modules/mdast-util-to-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0" @@ -5789,8 +4548,6 @@ }, "node_modules/merge2": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "license": "MIT", "engines": { "node": ">= 8" @@ -5798,8 +4555,6 @@ }, "node_modules/micromark": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", - "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", "funding": [ { "type": "GitHub Sponsors", @@ -5833,8 +4588,6 @@ }, "node_modules/micromark-core-commonmark": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", - "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", "funding": [ { "type": "GitHub Sponsors", @@ -5867,8 +4620,6 @@ }, "node_modules/micromark-extension-gfm": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", - "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", "license": "MIT", "dependencies": { "micromark-extension-gfm-autolink-literal": "^2.0.0", @@ -5887,8 +4638,6 @@ }, "node_modules/micromark-extension-gfm-autolink-literal": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", - "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", @@ -5903,8 +4652,6 @@ }, "node_modules/micromark-extension-gfm-footnote": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -5923,8 +4670,6 @@ }, "node_modules/micromark-extension-gfm-strikethrough": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", - "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -5941,8 +4686,6 @@ }, "node_modules/micromark-extension-gfm-table": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", - "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -5958,8 +4701,6 @@ }, "node_modules/micromark-extension-gfm-tagfilter": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", - "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", "license": "MIT", "dependencies": { "micromark-util-types": "^2.0.0" @@ -5971,8 +4712,6 @@ }, "node_modules/micromark-extension-gfm-task-list-item": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", - "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -5988,8 +4727,6 @@ }, "node_modules/micromark-factory-destination": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", - "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", "funding": [ { "type": "GitHub Sponsors", @@ -6009,8 +4746,6 @@ }, "node_modules/micromark-factory-label": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", - "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", "funding": [ { "type": "GitHub Sponsors", @@ -6031,8 +4766,6 @@ }, "node_modules/micromark-factory-space": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -6051,8 +4784,6 @@ }, "node_modules/micromark-factory-title": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", - "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", "funding": [ { "type": "GitHub Sponsors", @@ -6073,8 +4804,6 @@ }, "node_modules/micromark-factory-whitespace": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", - "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", "funding": [ { "type": "GitHub Sponsors", @@ -6095,8 +4824,6 @@ }, "node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -6115,8 +4842,6 @@ }, "node_modules/micromark-util-chunked": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", - "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", "funding": [ { "type": "GitHub Sponsors", @@ -6134,8 +4859,6 @@ }, "node_modules/micromark-util-classify-character": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", - "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", "funding": [ { "type": "GitHub Sponsors", @@ -6155,8 +4878,6 @@ }, "node_modules/micromark-util-combine-extensions": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", - "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", "funding": [ { "type": "GitHub Sponsors", @@ -6175,8 +4896,6 @@ }, "node_modules/micromark-util-decode-numeric-character-reference": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", - "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", "funding": [ { "type": "GitHub Sponsors", @@ -6194,8 +4913,6 @@ }, "node_modules/micromark-util-decode-string": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", - "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", "funding": [ { "type": "GitHub Sponsors", @@ -6216,8 +4933,6 @@ }, "node_modules/micromark-util-encode": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", - "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", "funding": [ { "type": "GitHub Sponsors", @@ -6232,8 +4947,6 @@ }, "node_modules/micromark-util-html-tag-name": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", - "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", "funding": [ { "type": "GitHub Sponsors", @@ -6248,8 +4961,6 @@ }, "node_modules/micromark-util-normalize-identifier": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", - "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", "funding": [ { "type": "GitHub Sponsors", @@ -6267,8 +4978,6 @@ }, "node_modules/micromark-util-resolve-all": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", - "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", "funding": [ { "type": "GitHub Sponsors", @@ -6286,8 +4995,6 @@ }, "node_modules/micromark-util-sanitize-uri": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", - "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", "funding": [ { "type": "GitHub Sponsors", @@ -6307,8 +5014,6 @@ }, "node_modules/micromark-util-subtokenize": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", - "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", "funding": [ { "type": "GitHub Sponsors", @@ -6329,8 +5034,6 @@ }, "node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -6345,8 +5048,6 @@ }, "node_modules/micromark-util-types": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", "funding": [ { "type": "GitHub Sponsors", @@ -6361,8 +5062,6 @@ }, "node_modules/micromatch": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -6374,14 +5073,10 @@ }, "node_modules/microseconds": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz", - "integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==", "license": "MIT" }, "node_modules/mime-db": { "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -6389,8 +5084,6 @@ }, "node_modules/mime-types": { "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -6401,8 +5094,6 @@ }, "node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -6413,9 +5104,6 @@ }, "node_modules/minimist": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6423,8 +5111,6 @@ }, "node_modules/minipass": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" @@ -6432,14 +5118,10 @@ }, "node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/mz": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", "license": "MIT", "dependencies": { "any-promise": "^1.0.0", @@ -6449,8 +5131,6 @@ }, "node_modules/nano-time": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz", - "integrity": "sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==", "license": "ISC", "dependencies": { "big-integer": "^1.6.16" @@ -6458,8 +5138,6 @@ }, "node_modules/nanoid": { "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "funding": [ { "type": "github", @@ -6476,8 +5154,6 @@ }, "node_modules/napi-postinstall": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.3.tgz", - "integrity": "sha512-uTp172LLXSxuSYHv/kou+f6KW3SMppU9ivthaVTXian9sOt3XM/zHYHpRZiLgQoxeWfYUnslNWQHF1+G71xcow==", "dev": true, "license": "MIT", "bin": { @@ -6492,15 +5168,11 @@ }, "node_modules/natural-compare": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true, "license": "MIT" }, "node_modules/next": { "version": "14.2.32", - "resolved": "https://registry.npmjs.org/next/-/next-14.2.32.tgz", - "integrity": "sha512-fg5g0GZ7/nFc09X8wLe6pNSU8cLWbLRG3TZzPJ1BJvi2s9m7eF991se67wliM9kR5yLHRkyGKU49MMx58s3LJg==", "license": "MIT", "dependencies": { "@next/env": "14.2.32", @@ -6549,8 +5221,6 @@ }, "node_modules/next-themes": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.2.1.tgz", - "integrity": "sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A==", "license": "MIT", "peerDependencies": { "next": "*", @@ -6560,8 +5230,6 @@ }, "node_modules/next/node_modules/postcss": { "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "funding": [ { "type": "opencollective", @@ -6586,27 +5254,8 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", - "dev": true, - "license": "MIT" - }, "node_modules/normalize-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -6614,8 +5263,6 @@ }, "node_modules/object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -6623,8 +5270,6 @@ }, "node_modules/object-hash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", "license": "MIT", "engines": { "node": ">= 6" @@ -6632,8 +5277,6 @@ }, "node_modules/object-inspect": { "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "dev": true, "license": "MIT", "engines": { @@ -6645,8 +5288,6 @@ }, "node_modules/object-keys": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, "license": "MIT", "engines": { @@ -6655,8 +5296,6 @@ }, "node_modules/object.assign": { "version": "4.1.7", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", - "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "dev": true, "license": "MIT", "dependencies": { @@ -6676,8 +5315,6 @@ }, "node_modules/object.entries": { "version": "1.1.9", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", - "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", "dev": true, "license": "MIT", "dependencies": { @@ -6692,8 +5329,6 @@ }, "node_modules/object.fromentries": { "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6711,8 +5346,6 @@ }, "node_modules/object.groupby": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6726,8 +5359,6 @@ }, "node_modules/object.values": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", - "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", "dev": true, "license": "MIT", "dependencies": { @@ -6745,14 +5376,10 @@ }, "node_modules/oblivious-set": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz", - "integrity": "sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw==", "license": "MIT" }, "node_modules/once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "license": "ISC", "dependencies": { "wrappy": "1" @@ -6760,8 +5387,6 @@ }, "node_modules/optionator": { "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "license": "MIT", "dependencies": { @@ -6778,8 +5403,6 @@ }, "node_modules/own-keys": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", - "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", "dev": true, "license": "MIT", "dependencies": { @@ -6796,8 +5419,6 @@ }, "node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6812,8 +5433,6 @@ }, "node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "license": "MIT", "dependencies": { @@ -6828,14 +5447,10 @@ }, "node_modules/package-json-from-dist": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "license": "BlueOak-1.0.0" }, "node_modules/parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "license": "MIT", "dependencies": { @@ -6847,8 +5462,6 @@ }, "node_modules/parse-entities": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", - "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", "license": "MIT", "dependencies": { "@types/unist": "^2.0.0", @@ -6866,14 +5479,10 @@ }, "node_modules/parse-entities/node_modules/@types/unist": { "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", - "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", "license": "MIT" }, "node_modules/path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "license": "MIT", "engines": { @@ -6882,8 +5491,6 @@ }, "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -6891,8 +5498,6 @@ }, "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "license": "MIT", "engines": { "node": ">=8" @@ -6900,14 +5505,10 @@ }, "node_modules/path-parse": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "license": "MIT" }, "node_modules/path-scurry": { "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", @@ -6922,8 +5523,6 @@ }, "node_modules/path-type": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, "license": "MIT", "engines": { @@ -6932,14 +5531,10 @@ }, "node_modules/picocolors": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "license": "MIT", "engines": { "node": ">=8.6" @@ -6950,8 +5545,6 @@ }, "node_modules/pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -6959,8 +5552,6 @@ }, "node_modules/pirates": { "version": "4.0.7", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", - "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", "license": "MIT", "engines": { "node": ">= 6" @@ -6968,8 +5559,6 @@ }, "node_modules/possible-typed-array-names": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", - "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", "dev": true, "license": "MIT", "engines": { @@ -6978,8 +5567,6 @@ }, "node_modules/postcss": { "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "funding": [ { "type": "opencollective", @@ -7006,8 +5593,6 @@ }, "node_modules/postcss-import": { "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.0.0", @@ -7023,8 +5608,6 @@ }, "node_modules/postcss-js": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", - "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", "license": "MIT", "dependencies": { "camelcase-css": "^2.0.1" @@ -7042,8 +5625,6 @@ }, "node_modules/postcss-nested": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", - "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", "funding": [ { "type": "opencollective", @@ -7067,8 +5648,6 @@ }, "node_modules/postcss-nested/node_modules/postcss-selector-parser": { "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -7080,8 +5659,6 @@ }, "node_modules/postcss-selector-parser": { "version": "6.0.10", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -7093,14 +5670,10 @@ }, "node_modules/postcss-value-parser": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "license": "MIT" }, "node_modules/prelude-ls": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "license": "MIT", "engines": { @@ -7109,8 +5682,6 @@ }, "node_modules/prop-types": { "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "dev": true, "license": "MIT", "dependencies": { @@ -7121,8 +5692,6 @@ }, "node_modules/property-information": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", - "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", "license": "MIT", "funding": { "type": "github", @@ -7131,14 +5700,10 @@ }, "node_modules/proxy-from-env": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "license": "MIT" }, "node_modules/punycode": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "license": "MIT", "engines": { @@ -7147,8 +5712,6 @@ }, "node_modules/queue-microtask": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "funding": [ { "type": "github", @@ -7167,8 +5730,6 @@ }, "node_modules/react": { "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" @@ -7179,8 +5740,6 @@ }, "node_modules/react-dom": { "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", @@ -7192,8 +5751,6 @@ }, "node_modules/react-hook-form": { "version": "7.62.0", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.62.0.tgz", - "integrity": "sha512-7KWFejc98xqG/F4bAxpL41NB3o1nnvQO1RWZT3TqRZYL8RryQETGfEdVnJN2fy1crCiBLLjkRBVK05j24FxJGA==", "license": "MIT", "engines": { "node": ">=18.0.0" @@ -7208,8 +5765,6 @@ }, "node_modules/react-hot-toast": { "version": "2.6.0", - "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.6.0.tgz", - "integrity": "sha512-bH+2EBMZ4sdyou/DPrfgIouFpcRLCJ+HoCA32UoAYHn6T3Ur5yfcDCeSr5mwldl6pFOsiocmrXMuoCJ1vV8bWg==", "license": "MIT", "dependencies": { "csstype": "^3.1.3", @@ -7225,15 +5780,11 @@ }, "node_modules/react-is": { "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true, "license": "MIT" }, "node_modules/react-markdown": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz", - "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -7259,8 +5810,6 @@ }, "node_modules/react-query": { "version": "3.39.3", - "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz", - "integrity": "sha512-nLfLz7GiohKTJDuT4us4X3h/8unOh+00MLb2yJoGTPjxKs2bc1iDhkNx2bd5MKklXnOD3NrVZ+J2UXujA5In4g==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.5.5", @@ -7285,8 +5834,6 @@ }, "node_modules/react-remove-scroll": { "version": "2.7.1", - "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz", - "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==", "license": "MIT", "dependencies": { "react-remove-scroll-bar": "^2.3.7", @@ -7310,8 +5857,6 @@ }, "node_modules/react-remove-scroll-bar": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", - "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", "license": "MIT", "dependencies": { "react-style-singleton": "^2.2.2", @@ -7332,8 +5877,6 @@ }, "node_modules/react-style-singleton": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", - "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", "license": "MIT", "dependencies": { "get-nonce": "^1.0.0", @@ -7354,8 +5897,6 @@ }, "node_modules/read-cache": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", "license": "MIT", "dependencies": { "pify": "^2.3.0" @@ -7363,8 +5904,6 @@ }, "node_modules/readdirp": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "license": "MIT", "dependencies": { "picomatch": "^2.2.1" @@ -7375,8 +5914,6 @@ }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", - "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", "dev": true, "license": "MIT", "dependencies": { @@ -7398,8 +5935,6 @@ }, "node_modules/regexp.prototype.flags": { "version": "1.5.4", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", - "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "dev": true, "license": "MIT", "dependencies": { @@ -7419,8 +5954,6 @@ }, "node_modules/rehype-highlight": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/rehype-highlight/-/rehype-highlight-7.0.2.tgz", - "integrity": "sha512-k158pK7wdC2qL3M5NcZROZ2tR/l7zOzjxXd5VGdcfIyoijjQqpHd3JKtYSBDpDZ38UI2WJWuFAtkMDxmx5kstA==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -7436,8 +5969,6 @@ }, "node_modules/remark-gfm": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", - "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -7454,8 +5985,6 @@ }, "node_modules/remark-parse": { "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -7470,8 +5999,6 @@ }, "node_modules/remark-rehype": { "version": "11.1.2", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", - "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -7487,8 +6014,6 @@ }, "node_modules/remark-stringify": { "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -7502,14 +6027,10 @@ }, "node_modules/remove-accents": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz", - "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==", "license": "MIT" }, "node_modules/resolve": { "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "license": "MIT", "dependencies": { "is-core-module": "^2.16.0", @@ -7528,8 +6049,6 @@ }, "node_modules/resolve-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, "license": "MIT", "engines": { @@ -7538,8 +6057,6 @@ }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true, "license": "MIT", "funding": { @@ -7548,8 +6065,6 @@ }, "node_modules/reusify": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -7558,9 +6073,6 @@ }, "node_modules/rimraf": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", "license": "ISC", "dependencies": { "glob": "^7.1.3" @@ -7574,8 +6086,6 @@ }, "node_modules/run-parallel": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "funding": [ { "type": "github", @@ -7597,8 +6107,6 @@ }, "node_modules/safe-array-concat": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", - "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", "dev": true, "license": "MIT", "dependencies": { @@ -7617,8 +6125,6 @@ }, "node_modules/safe-push-apply": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", - "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", "dev": true, "license": "MIT", "dependencies": { @@ -7634,8 +6140,6 @@ }, "node_modules/safe-regex-test": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", - "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", "dev": true, "license": "MIT", "dependencies": { @@ -7652,8 +6156,6 @@ }, "node_modules/scheduler": { "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" @@ -7661,8 +6163,6 @@ }, "node_modules/semver": { "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, "license": "ISC", "bin": { @@ -7674,8 +6174,6 @@ }, "node_modules/set-function-length": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, "license": "MIT", "dependencies": { @@ -7692,8 +6190,6 @@ }, "node_modules/set-function-name": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7708,8 +6204,6 @@ }, "node_modules/set-proto": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", - "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", "dev": true, "license": "MIT", "dependencies": { @@ -7723,8 +6217,6 @@ }, "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -7735,8 +6227,6 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "license": "MIT", "engines": { "node": ">=8" @@ -7744,8 +6234,6 @@ }, "node_modules/side-channel": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dev": true, "license": "MIT", "dependencies": { @@ -7764,8 +6252,6 @@ }, "node_modules/side-channel-list": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", "dev": true, "license": "MIT", "dependencies": { @@ -7781,8 +6267,6 @@ }, "node_modules/side-channel-map": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "dev": true, "license": "MIT", "dependencies": { @@ -7800,8 +6284,6 @@ }, "node_modules/side-channel-weakmap": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "dev": true, "license": "MIT", "dependencies": { @@ -7820,8 +6302,6 @@ }, "node_modules/signal-exit": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "license": "ISC", "engines": { "node": ">=14" @@ -7832,8 +6312,6 @@ }, "node_modules/slash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "license": "MIT", "engines": { @@ -7842,8 +6320,6 @@ }, "node_modules/source-map-js": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -7851,8 +6327,6 @@ }, "node_modules/space-separated-tokens": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", "license": "MIT", "funding": { "type": "github", @@ -7861,15 +6335,11 @@ }, "node_modules/stable-hash": { "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", - "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==", "dev": true, "license": "MIT" }, "node_modules/stop-iteration-iterator": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", - "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7882,16 +6352,12 @@ }, "node_modules/streamsearch": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", "engines": { "node": ">=10.0.0" } }, "node_modules/string-width": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", @@ -7908,8 +6374,6 @@ "node_modules/string-width-cjs": { "name": "string-width", "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -7922,14 +6386,10 @@ }, "node_modules/string-width-cjs/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, "node_modules/string-width/node_modules/ansi-regex": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz", - "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==", "license": "MIT", "engines": { "node": ">=12" @@ -7940,8 +6400,6 @@ }, "node_modules/string-width/node_modules/strip-ansi": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -7955,8 +6413,6 @@ }, "node_modules/string.prototype.includes": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", - "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", "dev": true, "license": "MIT", "dependencies": { @@ -7970,8 +6426,6 @@ }, "node_modules/string.prototype.matchall": { "version": "4.0.12", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", - "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", "dev": true, "license": "MIT", "dependencies": { @@ -7998,8 +6452,6 @@ }, "node_modules/string.prototype.repeat": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", - "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", "dev": true, "license": "MIT", "dependencies": { @@ -8009,8 +6461,6 @@ }, "node_modules/string.prototype.trim": { "version": "1.2.10", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", - "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", "dev": true, "license": "MIT", "dependencies": { @@ -8031,8 +6481,6 @@ }, "node_modules/string.prototype.trimend": { "version": "1.0.9", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", - "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8050,8 +6498,6 @@ }, "node_modules/string.prototype.trimstart": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, "license": "MIT", "dependencies": { @@ -8068,8 +6514,6 @@ }, "node_modules/stringify-entities": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", - "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", "license": "MIT", "dependencies": { "character-entities-html4": "^2.0.0", @@ -8082,8 +6526,6 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -8095,8 +6537,6 @@ "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -8107,9 +6547,6 @@ }, "node_modules/strip-bom": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -8117,8 +6554,6 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "license": "MIT", "engines": { @@ -8130,8 +6565,6 @@ }, "node_modules/style-to-js": { "version": "1.1.17", - "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.17.tgz", - "integrity": "sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA==", "license": "MIT", "dependencies": { "style-to-object": "1.0.9" @@ -8139,8 +6572,6 @@ }, "node_modules/style-to-object": { "version": "1.0.9", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.9.tgz", - "integrity": "sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==", "license": "MIT", "dependencies": { "inline-style-parser": "0.2.4" @@ -8148,8 +6579,6 @@ }, "node_modules/styled-jsx": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", - "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", "license": "MIT", "dependencies": { "client-only": "0.0.1" @@ -8171,8 +6600,6 @@ }, "node_modules/sucrase": { "version": "3.35.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", @@ -8193,8 +6620,6 @@ }, "node_modules/sucrase/node_modules/brace-expansion": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -8202,8 +6627,6 @@ }, "node_modules/sucrase/node_modules/glob": { "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -8222,8 +6645,6 @@ }, "node_modules/sucrase/node_modules/minimatch": { "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -8237,9 +6658,6 @@ }, "node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -8250,8 +6668,6 @@ }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -8262,8 +6678,6 @@ }, "node_modules/tailwind-merge": { "version": "2.6.0", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.0.tgz", - "integrity": "sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==", "license": "MIT", "funding": { "type": "github", @@ -8272,8 +6686,6 @@ }, "node_modules/tailwindcss": { "version": "3.4.17", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", - "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", @@ -8309,8 +6721,6 @@ }, "node_modules/tailwindcss-animate": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", - "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", "license": "MIT", "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders" @@ -8318,8 +6728,6 @@ }, "node_modules/tailwindcss/node_modules/postcss-load-config": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", - "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", "funding": [ { "type": "opencollective", @@ -8353,8 +6761,6 @@ }, "node_modules/tailwindcss/node_modules/postcss-selector-parser": { "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -8364,17 +6770,24 @@ "node": ">=4" } }, + "node_modules/tapable": { + "version": "2.2.3", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/text-table": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true, "license": "MIT" }, "node_modules/thenify": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", "license": "MIT", "dependencies": { "any-promise": "^1.0.0" @@ -8382,8 +6795,6 @@ }, "node_modules/thenify-all": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", "license": "MIT", "dependencies": { "thenify": ">= 3.1.0 < 4" @@ -8394,8 +6805,6 @@ }, "node_modules/tinyglobby": { "version": "0.2.14", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", - "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8411,8 +6820,6 @@ }, "node_modules/tinyglobby/node_modules/fdir": { "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", "engines": { @@ -8429,8 +6836,6 @@ }, "node_modules/tinyglobby/node_modules/picomatch": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", "engines": { @@ -8442,8 +6847,6 @@ }, "node_modules/to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -8454,8 +6857,6 @@ }, "node_modules/trim-lines": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", "license": "MIT", "funding": { "type": "github", @@ -8464,8 +6865,6 @@ }, "node_modules/trough": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", - "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", "license": "MIT", "funding": { "type": "github", @@ -8474,8 +6873,6 @@ }, "node_modules/ts-api-utils": { "version": "1.4.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", - "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", "dev": true, "license": "MIT", "engines": { @@ -8487,14 +6884,10 @@ }, "node_modules/ts-interface-checker": { "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", "license": "Apache-2.0" }, "node_modules/tsconfig-paths": { "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, "license": "MIT", "dependencies": { @@ -8504,16 +6897,47 @@ "strip-bom": "^3.0.0" } }, + "node_modules/tsconfig-paths-webpack-plugin": { + "version": "4.2.0", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.7.0", + "tapable": "^2.2.1", + "tsconfig-paths": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/tsconfig-paths-webpack-plugin/node_modules/json5": { + "version": "2.2.3", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tsconfig-paths-webpack-plugin/node_modules/tsconfig-paths": { + "version": "4.2.0", + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/tslib": { "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, "node_modules/type-check": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "license": "MIT", "dependencies": { @@ -8525,8 +6949,6 @@ }, "node_modules/type-fest": { "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { @@ -8538,8 +6960,6 @@ }, "node_modules/typed-array-buffer": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", - "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, "license": "MIT", "dependencies": { @@ -8553,8 +6973,6 @@ }, "node_modules/typed-array-byte-length": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", - "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", "dev": true, "license": "MIT", "dependencies": { @@ -8573,8 +6991,6 @@ }, "node_modules/typed-array-byte-offset": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", - "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8595,8 +7011,6 @@ }, "node_modules/typed-array-length": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", - "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "dev": true, "license": "MIT", "dependencies": { @@ -8616,8 +7030,6 @@ }, "node_modules/typescript": { "version": "5.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", - "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true, "license": "Apache-2.0", "bin": { @@ -8630,8 +7042,6 @@ }, "node_modules/unbox-primitive": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", - "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", "dev": true, "license": "MIT", "dependencies": { @@ -8649,15 +7059,11 @@ }, "node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, "node_modules/unified": { "version": "11.0.5", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", - "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -8675,8 +7081,6 @@ }, "node_modules/unist-util-find-after": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", - "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -8689,8 +7093,6 @@ }, "node_modules/unist-util-is": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" @@ -8702,8 +7104,6 @@ }, "node_modules/unist-util-position": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" @@ -8715,8 +7115,6 @@ }, "node_modules/unist-util-stringify-position": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" @@ -8728,8 +7126,6 @@ }, "node_modules/unist-util-visit": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -8743,8 +7139,6 @@ }, "node_modules/unist-util-visit-parents": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -8757,8 +7151,6 @@ }, "node_modules/unload": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/unload/-/unload-2.2.0.tgz", - "integrity": "sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==", "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.6.2", @@ -8767,8 +7159,6 @@ }, "node_modules/unrs-resolver": { "version": "1.11.1", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", - "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -8800,41 +7190,8 @@ "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" } }, - "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, "node_modules/uri-js": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -8843,8 +7200,6 @@ }, "node_modules/use-callback-ref": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", - "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", "license": "MIT", "dependencies": { "tslib": "^2.0.0" @@ -8864,8 +7219,6 @@ }, "node_modules/use-sidecar": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", - "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", "license": "MIT", "dependencies": { "detect-node-es": "^1.1.0", @@ -8886,8 +7239,6 @@ }, "node_modules/use-sync-external-store": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz", - "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==", "license": "MIT", "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" @@ -8895,14 +7246,10 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, "node_modules/vfile": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", - "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -8915,8 +7262,6 @@ }, "node_modules/vfile-message": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", - "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -8929,8 +7274,6 @@ }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -8944,8 +7287,6 @@ }, "node_modules/which-boxed-primitive": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", - "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", "dev": true, "license": "MIT", "dependencies": { @@ -8964,8 +7305,6 @@ }, "node_modules/which-builtin-type": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", - "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", "dev": true, "license": "MIT", "dependencies": { @@ -8992,8 +7331,6 @@ }, "node_modules/which-collection": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", - "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, "license": "MIT", "dependencies": { @@ -9011,8 +7348,6 @@ }, "node_modules/which-typed-array": { "version": "1.1.19", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", - "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "dev": true, "license": "MIT", "dependencies": { @@ -9033,8 +7368,6 @@ }, "node_modules/word-wrap": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "license": "MIT", "engines": { @@ -9043,8 +7376,6 @@ }, "node_modules/wrap-ansi": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", @@ -9061,8 +7392,6 @@ "node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -9078,14 +7407,10 @@ }, "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, "node_modules/wrap-ansi-cjs/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -9098,8 +7423,6 @@ }, "node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz", - "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==", "license": "MIT", "engines": { "node": ">=12" @@ -9110,8 +7433,6 @@ }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "license": "MIT", "engines": { "node": ">=12" @@ -9122,8 +7443,6 @@ }, "node_modules/wrap-ansi/node_modules/strip-ansi": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -9137,14 +7456,10 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC" }, "node_modules/yaml": { "version": "2.8.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", - "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", "license": "ISC", "bin": { "yaml": "bin.mjs" @@ -9155,8 +7470,6 @@ }, "node_modules/yocto-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "license": "MIT", "engines": { @@ -9168,8 +7481,6 @@ }, "node_modules/zod": { "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" @@ -9177,8 +7488,6 @@ }, "node_modules/zwitch": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", "license": "MIT", "funding": { "type": "github", diff --git a/frontend/package.json b/frontend/package.json index 7bb3a0f..663c315 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -57,7 +57,6 @@ "@types/node": "^20.10.0", "@types/react": "^18.2.39", "@types/react-dom": "^18.2.17", - "autoprefixer": "^10.4.16", "eslint": "^8.54.0", "eslint-config-next": "14.0.4", "postcss": "^8.4.32", diff --git a/frontend/src/app/test-auth/page.tsx b/frontend/src/app/test-auth/page.tsx index 94d316f..592ab52 100644 --- a/frontend/src/app/test-auth/page.tsx +++ b/frontend/src/app/test-auth/page.tsx @@ -26,16 +26,18 @@ export default function TestAuthPage() { const getTokenInfo = () => { const expiry = tokenManager.getTokenExpiry() const refreshExpiry = tokenManager.getRefreshTokenExpiry() - - if (!expiry) return "No token" - + + if (!expiry.access_token_expiry) return "No token" + const now = new Date() - const timeUntilExpiry = Math.floor((expiry.getTime() - now.getTime()) / 1000) - + const accessTimeUntilExpiry = Math.floor((expiry.access_token_expiry - now.getTime() / 1000)) + const refreshTimeUntilExpiry = refreshExpiry ? Math.floor((refreshExpiry - now.getTime() / 1000)) : null + return ` -Token expires in: ${Math.floor(timeUntilExpiry / 60)} minutes ${timeUntilExpiry % 60} seconds -Access token expiry: ${expiry.toLocaleString()} -Refresh token expiry: ${refreshExpiry?.toLocaleString() || 'N/A'} +Access token expires in: ${Math.floor(accessTimeUntilExpiry / 60)} minutes ${accessTimeUntilExpiry % 60} seconds +Refresh token expires in: ${refreshTimeUntilExpiry ? `${Math.floor(refreshTimeUntilExpiry / 60)} minutes ${refreshTimeUntilExpiry % 60} seconds` : 'N/A'} +Access token expiry: ${new Date(expiry.access_token_expiry * 1000).toLocaleString()} +Refresh token expiry: ${refreshExpiry ? new Date(refreshExpiry * 1000).toLocaleString() : 'N/A'} Authenticated: ${tokenManager.isAuthenticated()} ` } From 965002687b7d140c034d7020e10bf1305cbdd679 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Tue, 16 Sep 2025 11:23:24 +0200 Subject: [PATCH 16/43] gh build --- .github/workflows/build-all.yml | 125 ++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 .github/workflows/build-all.yml diff --git a/.github/workflows/build-all.yml b/.github/workflows/build-all.yml new file mode 100644 index 0000000..045d344 --- /dev/null +++ b/.github/workflows/build-all.yml @@ -0,0 +1,125 @@ +name: Build All Docker Images + +on: + push: + branches: [ main, develop ] + tags: [ 'v*' ] + pull_request: + branches: [ main ] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-frontend: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Container registry + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata for frontend + id: meta-frontend + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-frontend + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=raw,value=latest,enable={{is_default_branch}} + + - name: Build and push frontend Docker image + uses: docker/build-push-action@v5 + with: + context: ./frontend + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta-frontend.outputs.tags }} + labels: ${{ steps.meta-frontend.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + build-backend: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Container registry + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata for backend + id: meta-backend + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-backend + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=raw,value=latest,enable={{is_default_branch}} + + - name: Build and push backend Docker image + uses: docker/build-push-action@v5 + with: + context: ./backend + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta-backend.outputs.tags }} + labels: ${{ steps.meta-backend.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + # Optional: Create a combined manifest or documentation + document-images: + runs-on: ubuntu-latest + needs: [build-frontend, build-backend] + if: github.event_name != 'pull_request' + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Generate image documentation + run: | + echo "# Built Images" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "## Frontend Image" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY + echo "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-frontend:${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "## Backend Image" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY + echo "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-backend:${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY \ No newline at end of file From d0535a07d6bf88479e5dbee0da1200345503a1f0 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Tue, 16 Sep 2025 11:31:36 +0200 Subject: [PATCH 17/43] lib --- frontend/src/lib/api-client.ts | 97 ++++++++++++++++ frontend/src/lib/config.ts | 49 +++++++++ frontend/src/lib/file-download.ts | 119 ++++++++++++++++++++ frontend/src/lib/id-utils.ts | 36 ++++++ frontend/src/lib/proxy-auth.ts | 176 ++++++++++++++++++++++++++++++ frontend/src/lib/token-manager.ts | 99 +++++++++++++++++ frontend/src/lib/utils.ts | 98 +++++++++++++++++ 7 files changed, 674 insertions(+) create mode 100644 frontend/src/lib/api-client.ts create mode 100644 frontend/src/lib/config.ts create mode 100644 frontend/src/lib/file-download.ts create mode 100644 frontend/src/lib/id-utils.ts create mode 100644 frontend/src/lib/proxy-auth.ts create mode 100644 frontend/src/lib/token-manager.ts create mode 100644 frontend/src/lib/utils.ts diff --git a/frontend/src/lib/api-client.ts b/frontend/src/lib/api-client.ts new file mode 100644 index 0000000..75ae0aa --- /dev/null +++ b/frontend/src/lib/api-client.ts @@ -0,0 +1,97 @@ +import axios from 'axios'; +import Cookies from 'js-cookie'; + +const API_BASE_URL = process.env.NEXT_PUBLIC_BASE_URL || ''; + +const axiosInstance = axios.create({ + baseURL: API_BASE_URL, + headers: { + 'Content-Type': 'application/json', + }, +}); + +// Request interceptor to add auth token +axiosInstance.interceptors.request.use( + (config) => { + const token = Cookies.get('access_token'); + if (token) { + config.headers.Authorization = `Bearer ${token}`; + } + return config; + }, + (error) => { + return Promise.reject(error); + } +); + +// Response interceptor to handle token refresh +axiosInstance.interceptors.response.use( + (response) => response, + async (error) => { + const originalRequest = error.config; + + if (error.response?.status === 401 && !originalRequest._retry) { + originalRequest._retry = true; + + try { + const refreshToken = Cookies.get('refresh_token'); + if (refreshToken) { + const response = await axios.post(`${API_BASE_URL}/api/auth/refresh`, { + refresh_token: refreshToken, + }); + + const { access_token } = response.data; + Cookies.set('access_token', access_token, { expires: 7 }); + + originalRequest.headers.Authorization = `Bearer ${access_token}`; + return axiosInstance(originalRequest); + } + } catch (refreshError) { + // Refresh failed, redirect to login + Cookies.remove('access_token'); + Cookies.remove('refresh_token'); + window.location.href = '/login'; + return Promise.reject(refreshError); + } + } + + return Promise.reject(error); + } +); + +export const apiClient = { + get: async (url: string, config?: any): Promise => { + const response = await axiosInstance.get(url, config); + return response.data; + }, + + post: async (url: string, data?: any, config?: any): Promise => { + const response = await axiosInstance.post(url, data, config); + return response.data; + }, + + put: async (url: string, data?: any, config?: any): Promise => { + const response = await axiosInstance.put(url, data, config); + return response.data; + }, + + delete: async (url: string, config?: any): Promise => { + const response = await axiosInstance.delete(url, config); + return response.data; + }, + + patch: async (url: string, data?: any, config?: any): Promise => { + const response = await axiosInstance.patch(url, data, config); + return response.data; + }, +}; + +// Chatbot specific API methods +export const chatbotApi = { + create: async (data: any) => apiClient.post('/api/chatbot/create', data), + list: async () => apiClient.get('/api/chatbot/list'), + update: async (id: string, data: any) => apiClient.put(`/api/chatbot/update/${id}`, data), + delete: async (id: string) => apiClient.delete(`/api/chatbot/delete/${id}`), + chat: async (id: string, message: string, config?: any) => + apiClient.post(`/api/chatbot/chat`, { chatbot_id: id, message, ...config }), +}; \ No newline at end of file diff --git a/frontend/src/lib/config.ts b/frontend/src/lib/config.ts new file mode 100644 index 0000000..479c7bc --- /dev/null +++ b/frontend/src/lib/config.ts @@ -0,0 +1,49 @@ +export const config = { + API_BASE_URL: process.env.NEXT_PUBLIC_BASE_URL || '', + APP_NAME: process.env.NEXT_PUBLIC_APP_NAME || 'Enclava', + DEFAULT_LANGUAGE: 'en', + SUPPORTED_LANGUAGES: ['en', 'es', 'fr', 'de', 'it'], + + // Feature flags + FEATURES: { + RAG: true, + PLUGINS: true, + ANALYTICS: true, + AUDIT_LOGS: true, + BUDGET_MANAGEMENT: true, + }, + + // Default values + DEFAULTS: { + TEMPERATURE: 0.7, + MAX_TOKENS: 1000, + TOP_K: 5, + MEMORY_LENGTH: 10, + }, + + // API endpoints + ENDPOINTS: { + AUTH: { + LOGIN: '/api/auth/login', + REGISTER: '/api/auth/register', + REFRESH: '/api/auth/refresh', + ME: '/api/auth/me', + }, + CHATBOT: { + LIST: '/api/chatbot/list', + CREATE: '/api/chatbot/create', + UPDATE: '/api/chatbot/update/:id', + DELETE: '/api/chatbot/delete/:id', + CHAT: '/api/chatbot/chat', + }, + LLM: { + MODELS: '/api/llm/models', + API_KEYS: '/api/llm/api-keys', + BUDGETS: '/api/llm/budgets', + }, + RAG: { + COLLECTIONS: '/api/rag/collections', + DOCUMENTS: '/api/rag/documents', + }, + }, +}; \ No newline at end of file diff --git a/frontend/src/lib/file-download.ts b/frontend/src/lib/file-download.ts new file mode 100644 index 0000000..bb0ea2e --- /dev/null +++ b/frontend/src/lib/file-download.ts @@ -0,0 +1,119 @@ +export const downloadFile = async (url: string, filename?: string): Promise => { + try { + const response = await fetch(url); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + // Get the filename from the response headers if not provided + const contentDisposition = response.headers.get('Content-Disposition'); + let defaultFilename = filename || 'download'; + + if (contentDisposition) { + const filenameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/); + if (filenameMatch && filenameMatch[1]) { + defaultFilename = filenameMatch[1].replace(/['"]/g, ''); + } + } + + // Get the blob from the response + const blob = await response.blob(); + + // Create a temporary URL for the blob + const blobUrl = window.URL.createObjectURL(blob); + + // Create a temporary link element + const link = document.createElement('a'); + link.href = blobUrl; + link.download = defaultFilename; + + // Append the link to the body + document.body.appendChild(link); + + // Trigger the download + link.click(); + + // Clean up + document.body.removeChild(link); + window.URL.revokeObjectURL(blobUrl); + } catch (error) { + console.error('Error downloading file:', error); + throw error; + } +}; + +export const downloadFileFromData = ( + data: Blob | string, + filename: string, + mimeType?: string +): void => { + try { + let blob: Blob; + + if (typeof data === 'string') { + blob = new Blob([data], { type: mimeType || 'text/plain' }); + } else { + blob = data; + } + + const blobUrl = window.URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = blobUrl; + link.download = filename; + + document.body.appendChild(link); + link.click(); + + document.body.removeChild(link); + window.URL.revokeObjectURL(blobUrl); + } catch (error) { + console.error('Error downloading file from data:', error); + throw error; + } +}; + +export const uploadFile = async ( + file: File, + url: string, + onProgress?: (progress: number) => void +): Promise => { + try { + const formData = new FormData(); + formData.append('file', file); + + const xhr = new XMLHttpRequest(); + + return new Promise((resolve, reject) => { + xhr.upload.onprogress = (event) => { + if (event.lengthComputable && onProgress) { + const progress = (event.loaded / event.total) * 100; + onProgress(progress); + } + }; + + xhr.onload = () => { + if (xhr.status >= 200 && xhr.status < 300) { + try { + const response = JSON.parse(xhr.responseText); + resolve(response); + } catch (error) { + resolve(xhr.responseText); + } + } else { + reject(new Error(`Upload failed with status ${xhr.status}`)); + } + }; + + xhr.onerror = () => { + reject(new Error('Network error during upload')); + }; + + xhr.open('POST', url, true); + xhr.send(formData); + }); + } catch (error) { + console.error('Error uploading file:', error); + throw error; + } +}; \ No newline at end of file diff --git a/frontend/src/lib/id-utils.ts b/frontend/src/lib/id-utils.ts new file mode 100644 index 0000000..16551f8 --- /dev/null +++ b/frontend/src/lib/id-utils.ts @@ -0,0 +1,36 @@ +export function generateId(): string { + return Math.random().toString(36).substr(2, 9); +} + +export function generateUniqueId(): string { + return Date.now().toString(36) + Math.random().toString(36).substr(2); +} + +export function generateMessageId(): string { + return `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; +} + +export function generateChatId(): string { + return `chat_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`; +} + +export function generateSessionId(): string { + return `sess_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`; +} + +export function generateShortId(): string { + return Math.random().toString(36).substr(2, 6); +} + +export function generateTimestampId(): string { + return `ts_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`; +} + +export function isValidId(id: string): boolean { + return typeof id === 'string' && id.length > 0; +} + +export function extractIdFromUrl(url: string): string | null { + const match = url.match(/\/([a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12})$/); + return match ? match[1] : null; +} \ No newline at end of file diff --git a/frontend/src/lib/proxy-auth.ts b/frontend/src/lib/proxy-auth.ts new file mode 100644 index 0000000..201a547 --- /dev/null +++ b/frontend/src/lib/proxy-auth.ts @@ -0,0 +1,176 @@ +import { NextRequest, NextResponse } from 'next/server'; + +// This is a proxy auth utility for server-side API routes +// It handles authentication and proxying requests to the backend + +export interface ProxyAuthConfig { + backendUrl: string; + requireAuth?: boolean; + allowedRoles?: string[]; +} + +export class ProxyAuth { + private config: ProxyAuthConfig; + + constructor(config: ProxyAuthConfig) { + this.config = { + requireAuth: true, + ...config, + }; + } + + async authenticate(request: NextRequest): Promise<{ success: boolean; user?: any; error?: string }> { + // For server-side auth, we would typically validate the token + // This is a simplified implementation + const authHeader = request.headers.get('authorization'); + + if (!authHeader || !authHeader.startsWith('Bearer ')) { + return { success: false, error: 'Missing or invalid authorization header' }; + } + + const token = authHeader.substring(7); + + // Here you would validate the token with your auth service + // For now, we'll just check if it exists + if (!token) { + return { success: false, error: 'Invalid token' }; + } + + // In a real implementation, you would decode and validate the JWT + // and check user roles if required + return { + success: true, + user: { + id: 'user-id', + email: 'user@example.com', + role: 'user' + } + }; + } + + async proxyRequest( + request: NextRequest, + path: string, + options?: { + method?: string; + headers?: Record; + body?: any; + } + ): Promise { + // Authenticate the request if required + if (this.config.requireAuth) { + const authResult = await this.authenticate(request); + if (!authResult.success) { + return NextResponse.json( + { error: authResult.error || 'Authentication failed' }, + { status: 401 } + ); + } + + // Check roles if specified + if (this.config.allowedRoles && authResult.user) { + if (!this.config.allowedRoles.includes(authResult.user.role)) { + return NextResponse.json( + { error: 'Insufficient permissions' }, + { status: 403 } + ); + } + } + } + + // Build the target URL + const targetUrl = new URL(path, this.config.backendUrl); + + // Copy query parameters + targetUrl.search = request.nextUrl.search; + + // Prepare headers + const headers: Record = { + 'Content-Type': 'application/json', + ...options?.headers, + }; + + // Forward authorization header if present + const authHeader = request.headers.get('authorization'); + if (authHeader) { + headers.authorization = authHeader; + } + + try { + const response = await fetch(targetUrl, { + method: options?.method || request.method, + headers, + body: options?.body ? JSON.stringify(options.body) : request.body, + }); + + // Create a new response with the data + const data = await response.json(); + + return NextResponse.json(data, { + status: response.status, + headers: { + 'Content-Type': 'application/json', + }, + }); + } catch (error) { + console.error('Proxy request failed:', error); + return NextResponse.json( + { error: 'Internal server error' }, + { status: 500 } + ); + } + } +} + +// Utility function to create a proxy handler +export function createProxyHandler(config: ProxyAuthConfig) { + const proxyAuth = new ProxyAuth(config); + + return async (request: NextRequest, { params }: { params: { path?: string[] } }) => { + const path = params?.path ? params.path.join('/') : ''; + return proxyAuth.proxyRequest(request, path); + }; +} + +// Simplified proxy request function for direct usage +export async function proxyRequest( + request: NextRequest, + backendUrl: string, + path: string = '', + options?: { + method?: string; + headers?: Record; + body?: any; + requireAuth?: boolean; + } +): Promise { + const proxyAuth = new ProxyAuth({ + backendUrl, + requireAuth: options?.requireAuth ?? true, + }); + + return proxyAuth.proxyRequest(request, path, options); +} + +// Helper function to handle proxy responses with error handling +export async function handleProxyResponse( + request: NextRequest, + backendUrl: string, + path: string = '', + options?: { + method?: string; + headers?: Record; + body?: any; + requireAuth?: boolean; + } +): Promise { + try { + return await proxyRequest(request, backendUrl, path, options); + } catch (error) { + console.error('Proxy request failed:', error); + return NextResponse.json( + { error: 'Internal server error' }, + { status: 500 } + ); + } +} \ No newline at end of file diff --git a/frontend/src/lib/token-manager.ts b/frontend/src/lib/token-manager.ts new file mode 100644 index 0000000..657d6a6 --- /dev/null +++ b/frontend/src/lib/token-manager.ts @@ -0,0 +1,99 @@ +import Cookies from 'js-cookie'; +import { EventEmitter } from 'events'; + +interface TokenManagerEvents { + tokensUpdated: []; + tokensCleared: []; +} + +export interface TokenManagerInterface { + getTokens(): { access_token: string | null; refresh_token: string | null }; + setTokens(access_token: string, refresh_token: string): void; + clearTokens(): void; + isAuthenticated(): boolean; + getAccessToken(): string | null; + getRefreshToken(): string | null; + getTokenExpiry(): { access_token_expiry: number | null; refresh_token_expiry: number | null }; + on( + event: E, + listener: (...args: TokenManagerEvents[E]) => void + ): this; + off( + event: E, + listener: (...args: TokenManagerEvents[E]) => void + ): this; +} + +class TokenManager extends EventEmitter implements TokenManagerInterface { + private static instance: TokenManager; + + private constructor() { + super(); + // Set max listeners to avoid memory leak warnings + this.setMaxListeners(100); + } + + static getInstance(): TokenManager { + if (!TokenManager.instance) { + TokenManager.instance = new TokenManager(); + } + return TokenManager.instance; + } + + getTokens() { + return { + access_token: Cookies.get('access_token'), + refresh_token: Cookies.get('refresh_token'), + }; + } + + setTokens(access_token: string, refresh_token: string) { + // Set cookies with secure attributes + Cookies.set('access_token', access_token, { + expires: 7, // 7 days + secure: process.env.NODE_ENV === 'production', + sameSite: 'strict', + }); + + Cookies.set('refresh_token', refresh_token, { + expires: 30, // 30 days + secure: process.env.NODE_ENV === 'production', + sameSite: 'strict', + }); + + // Emit event + this.emit('tokensUpdated'); + } + + clearTokens() { + Cookies.remove('access_token'); + Cookies.remove('refresh_token'); + this.emit('tokensCleared'); + } + + isAuthenticated(): boolean { + return !!this.getAccessToken(); + } + + getAccessToken(): string | null { + return Cookies.get('access_token'); + } + + getRefreshToken(): string | null { + return Cookies.get('refresh_token'); + } + + getTokenExpiry(): { access_token_expiry: number | null; refresh_token_expiry: number | null } { + return { + access_token_expiry: parseInt(Cookies.get('access_token_expiry') || '0') || null, + refresh_token_expiry: parseInt(Cookies.get('refresh_token_expiry') || '0') || null, + }; + } + + getRefreshTokenExpiry(): number | null { + return parseInt(Cookies.get('refresh_token_expiry') || '0') || null; + } +} + +// Export singleton instance +export const tokenManager = TokenManager.getInstance(); \ No newline at end of file diff --git a/frontend/src/lib/utils.ts b/frontend/src/lib/utils.ts new file mode 100644 index 0000000..b98093e --- /dev/null +++ b/frontend/src/lib/utils.ts @@ -0,0 +1,98 @@ +import { type ClassValue, clsx } from "clsx" +import { twMerge } from "tailwind-merge" + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} + +export function formatDate(date: Date | string): string { + const d = new Date(date); + return d.toLocaleDateString('en-US', { + year: 'numeric', + month: 'short', + day: 'numeric', + }); +} + +export function formatDateTime(date: Date | string): string { + const d = new Date(date); + return d.toLocaleString('en-US', { + year: 'numeric', + month: 'short', + day: 'numeric', + hour: '2-digit', + minute: '2-digit', + }); +} + +export function formatRelativeTime(date: Date | string): string { + const d = new Date(date); + const now = new Date(); + const diffMs = now.getTime() - d.getTime(); + const diffSeconds = Math.floor(diffMs / 1000); + const diffMinutes = Math.floor(diffSeconds / 60); + const diffHours = Math.floor(diffMinutes / 60); + const diffDays = Math.floor(diffHours / 24); + + if (diffSeconds < 60) return 'just now'; + if (diffMinutes < 60) return `${diffMinutes} minute${diffMinutes > 1 ? 's' : ''} ago`; + if (diffHours < 24) return `${diffHours} hour${diffHours > 1 ? 's' : ''} ago`; + if (diffDays < 7) return `${diffDays} day${diffDays > 1 ? 's' : ''} ago`; + + return formatDate(d); +} + +export function formatBytes(bytes: number, decimals = 2): string { + if (bytes === 0) return '0 Bytes'; + + const k = 1024; + const dm = decimals < 0 ? 0 : decimals; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; + + const i = Math.floor(Math.log(bytes) / Math.log(k)); + + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; +} + +export function formatNumber(num: number): string { + return new Intl.NumberFormat('en-US').format(num); +} + +export function formatCurrency(amount: number, currency = 'USD'): string { + return new Intl.NumberFormat('en-US', { + style: 'currency', + currency, + }).format(amount); +} + +export function truncate(str: string, length: number): string { + if (str.length <= length) return str; + return str.slice(0, length) + '...'; +} + +export function debounce any>( + func: T, + wait: number +): (...args: Parameters) => void { + let timeout: NodeJS.Timeout; + + return (...args: Parameters) => { + clearTimeout(timeout); + timeout = setTimeout(() => func(...args), wait); + }; +} + +export function throttle any>( + func: T, + limit: number +): (...args: Parameters) => void { + let inThrottle: boolean; + + return (...args: Parameters) => { + if (!inThrottle) { + func(...args); + inThrottle = true; + setTimeout(() => (inThrottle = false), limit); + } + }; +} \ No newline at end of file From 19dd1f07cb2c84425198b11aec4d20a43dc38db9 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Tue, 16 Sep 2025 11:43:12 +0200 Subject: [PATCH 18/43] fixing qdrant config mount --- docker-compose.prod.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 3afaa4c..969e428 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -138,7 +138,6 @@ services: - QDRANT__LOG_LEVEL=INFO volumes: - enclava-qdrant-data:/qdrant/storage - - ./qdrant/config.yaml:/qdrant/config/production.yaml:ro networks: - enclava-net restart: unless-stopped From be3a9002b3a7f0af5f462769353d9c340a9d610f Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Tue, 16 Sep 2025 17:50:51 +0200 Subject: [PATCH 19/43] potential fix --- frontend/src/lib/config.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/frontend/src/lib/config.ts b/frontend/src/lib/config.ts index 479c7bc..f54d0e9 100644 --- a/frontend/src/lib/config.ts +++ b/frontend/src/lib/config.ts @@ -3,6 +3,17 @@ export const config = { APP_NAME: process.env.NEXT_PUBLIC_APP_NAME || 'Enclava', DEFAULT_LANGUAGE: 'en', SUPPORTED_LANGUAGES: ['en', 'es', 'fr', 'de', 'it'], + getPublicApiUrl() { + if (this.API_BASE_URL) { + return this.API_BASE_URL + } + + if (typeof window !== 'undefined' && window.location.origin) { + return window.location.origin + } + + return '' + }, // Feature flags FEATURES: { @@ -46,4 +57,4 @@ export const config = { DOCUMENTS: '/api/rag/documents', }, }, -}; \ No newline at end of file +}; From 2912b99aa195e9b8e3e3cb507e2034e87f7e27d4 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Wed, 17 Sep 2025 09:52:47 +0200 Subject: [PATCH 20/43] cleaup env --- .env.example | 50 +++++++++++-------- backend/app/core/config.py | 3 +- docker-compose.prod.yml | 10 ++-- docker-compose.yml | 5 +- frontend/src/app/layout.tsx | 17 ++++++- .../src/components/rag/document-upload.tsx | 3 +- frontend/src/components/ui/user-menu.tsx | 12 ++++- frontend/src/contexts/AuthContext.tsx | 14 +++++- frontend/src/lib/api-client.ts | 19 +++++-- frontend/src/lib/file-download.ts | 10 +++- 10 files changed, 105 insertions(+), 38 deletions(-) diff --git a/.env.example b/.env.example index fed060d..3f2734c 100644 --- a/.env.example +++ b/.env.example @@ -1,9 +1,19 @@ # =================================== -# ENCLAVA MINIMAL CONFIGURATION +# ENCLAVA CONFIGURATION # =================================== # Only essential environment variables that CANNOT have defaults # Other settings should be configurable through the app UI +# Admin user (created on first startup only) +ADMIN_EMAIL=admin@example.com +ADMIN_PASSWORD=admin123 + + +# =================================== +# APPLICATION BASE URL (Required - derives all URLs and CORS) +# =================================== +BASE_URL=localhost + # =================================== # INFRASTRUCTURE (Required) # =================================== @@ -18,9 +28,7 @@ POSTGRES_PASSWORD=enclava_pass JWT_SECRET=your-super-secret-jwt-key-here-change-in-production PRIVATEMODE_API_KEY=your-privatemode-api-key-here -# Admin user (created on first startup only) -ADMIN_EMAIL=admin@example.com -ADMIN_PASSWORD=admin123 + # =================================== # ADDITIONAL SECURITY SETTINGS (Optional but recommended) @@ -36,29 +44,31 @@ ADMIN_PASSWORD=admin123 # API Key prefix (default: en_) # API_KEY_PREFIX=en_ -# Security thresholds (0.0-1.0) -# API_SECURITY_RISK_THRESHOLD=0.8 -# API_SECURITY_WARNING_THRESHOLD=0.6 -# API_SECURITY_ANOMALY_THRESHOLD=0.7 -# IP security (comma-separated for multiple IPs) -# API_BLOCKED_IPS= -# API_ALLOWED_IPS= # =================================== -# APPLICATION BASE URL (Required - derives all URLs and CORS) +# FRONTEND ENVIRONMENT (Required for production) # =================================== -BASE_URL=localhost -# Frontend derives: APP_URL=http://localhost, API_URL=http://localhost, WS_URL=ws://localhost -# Backend derives: CORS_ORIGINS=["http://localhost"] +NODE_ENV=production +NEXT_PUBLIC_APP_NAME=Enclava +# NEXT_PUBLIC_BASE_URL is derived from BASE_URL in Docker configuration # =================================== -# DOCKER NETWORKING (Required for containers) +# LOGGING CONFIGURATION # =================================== -BACKEND_INTERNAL_PORT=8000 -FRONTEND_INTERNAL_PORT=3000 -# Hosts are fixed: enclava-backend, enclava-frontend -# Upstreams derive: enclava-backend:8000, enclava-frontend:3000 +LOG_LLM_PROMPTS=false + +# For production HTTPS deployments, set: +# BASE_URL=your-domain.com +# The system will automatically detect HTTPS and use it for all URLs and CORS + +# =================================== +# DOCKER NETWORKING (Optional - defaults provided) +# =================================== +# Internal ports use defaults: backend=8000, frontend=3000 +# Override only if you need to change these defaults: +# BACKEND_INTERNAL_PORT=8000 +# FRONTEND_INTERNAL_PORT=3000 # =================================== # QDRANT (Required for RAG) diff --git a/backend/app/core/config.py b/backend/app/core/config.py index c5cb8c3..2c1ae90 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -48,7 +48,8 @@ class Settings(BaseSettings): """Derive CORS origins from BASE_URL if not explicitly set""" if v is None: base_url = info.data.get('BASE_URL', 'localhost') - return [f"http://{base_url}"] + # Support both HTTP and HTTPS for production environments + return [f"http://{base_url}", f"https://{base_url}"] return v if isinstance(v, list) else [v] # CORS origins (derived from BASE_URL) diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 969e428..2ce3e9f 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -23,9 +23,11 @@ services: # Database migration service - runs once to apply migrations enclava-migrate: - build: + build: context: ./backend dockerfile: Dockerfile.prod + env_file: + - ./.env environment: - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@enclava-postgres:5432/${POSTGRES_DB} depends_on: @@ -40,6 +42,8 @@ services: build: context: ./backend dockerfile: Dockerfile.prod + env_file: + - ./.env environment: - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@enclava-postgres:5432/${POSTGRES_DB} - REDIS_URL=redis://enclava-redis:6379 @@ -76,11 +80,11 @@ services: context: ./frontend dockerfile: Dockerfile target: runner # Use the production stage from multi-stage build + env_file: + - ./.env environment: - BASE_URL=${BASE_URL} - NEXT_PUBLIC_BASE_URL=${BASE_URL} - - BACKEND_INTERNAL_PORT=8000 - - FRONTEND_INTERNAL_PORT=3000 - INTERNAL_API_URL=http://enclava-backend:8000 - NODE_ENV=production - NEXT_TELEMETRY_DISABLED=1 diff --git a/docker-compose.yml b/docker-compose.yml index 8210ba9..ab9859a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -68,11 +68,8 @@ services: # Required base URL (derives APP/API/WS URLs) - BASE_URL=${BASE_URL} - NEXT_PUBLIC_BASE_URL=${BASE_URL} - # Docker internal ports - - BACKEND_INTERNAL_PORT=${BACKEND_INTERNAL_PORT} - - FRONTEND_INTERNAL_PORT=${FRONTEND_INTERNAL_PORT} # Internal API URL - - INTERNAL_API_URL=http://enclava-backend:${BACKEND_INTERNAL_PORT} + - INTERNAL_API_URL=http://enclava-backend:8000 depends_on: - enclava-backend ports: diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index ecc7af7..e0f3c58 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -16,8 +16,21 @@ export const viewport: Viewport = { initialScale: 1, } +// Function to determine the base URL with proper protocol +const getBaseUrl = () => { + // In production, we need to detect if we're behind HTTPS + if (typeof window !== 'undefined') { + const protocol = window.location.protocol === 'https:' ? 'https' : 'http' + const host = process.env.NEXT_PUBLIC_BASE_URL || window.location.hostname + return `${protocol}://${host}` + } + // For build time/server side, default to HTTP for dev, HTTPS for production + const protocol = process.env.NODE_ENV === 'production' ? 'https' : 'http' + return `${protocol}://${process.env.NEXT_PUBLIC_BASE_URL || 'localhost'}` +} + export const metadata: Metadata = { - metadataBase: new URL(`http://${process.env.NEXT_PUBLIC_BASE_URL || 'localhost'}`), + metadataBase: new URL(getBaseUrl()), title: 'Enclava Platform', description: 'Secure AI processing platform with plugin-based architecture and confidential computing', keywords: ['AI', 'Enclava', 'Confidential Computing', 'LLM', 'TEE'], @@ -26,7 +39,7 @@ export const metadata: Metadata = { openGraph: { type: 'website', locale: 'en_US', - url: `http://${process.env.NEXT_PUBLIC_BASE_URL || 'localhost'}`, + url: getBaseUrl(), title: 'Enclava Platform', description: 'Secure AI processing platform with plugin-based architecture and confidential computing', siteName: 'Enclava', diff --git a/frontend/src/components/rag/document-upload.tsx b/frontend/src/components/rag/document-upload.tsx index 387bc8c..040eefb 100644 --- a/frontend/src/components/rag/document-upload.tsx +++ b/frontend/src/components/rag/document-upload.tsx @@ -91,8 +91,9 @@ export function DocumentUpload({ collections, selectedCollection, onDocumentUplo updateProgress(60) await uploadFile( - '/api-internal/v1/rag/documents', uploadingFile.file, + '/api-internal/v1/rag/documents', + (progress) => updateProgress(progress), { collection_id: targetCollection } ) diff --git a/frontend/src/components/ui/user-menu.tsx b/frontend/src/components/ui/user-menu.tsx index cbec7cc..78e070d 100644 --- a/frontend/src/components/ui/user-menu.tsx +++ b/frontend/src/components/ui/user-menu.tsx @@ -18,6 +18,16 @@ import { import { User, Settings, Lock, LogOut, ChevronDown } from "lucide-react" import { useState } from "react" +// Helper function to get API URL with proper protocol +const getApiUrl = () => { + if (typeof window !== 'undefined') { + const protocol = window.location.protocol.slice(0, -1) // Remove ':' from 'https:' + const host = window.location.hostname + return `${protocol}://${host}` + } + return `http://${process.env.NEXT_PUBLIC_BASE_URL || 'localhost'}` +} + export function UserMenu() { const { user, logout } = useAuth() const { toast } = useToast() @@ -62,7 +72,7 @@ export function UserMenu() { throw new Error('Authentication required') } - const response = await fetch('/api-internal/v1/auth/change-password', { + const response = await fetch(`${getApiUrl()}/api-internal/v1/auth/change-password`, { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/frontend/src/contexts/AuthContext.tsx b/frontend/src/contexts/AuthContext.tsx index c5be4be..33030d8 100644 --- a/frontend/src/contexts/AuthContext.tsx +++ b/frontend/src/contexts/AuthContext.tsx @@ -4,6 +4,16 @@ import { createContext, useContext, useState, useEffect, ReactNode } from "react import { useRouter } from "next/navigation" import { tokenManager } from "@/lib/token-manager" +// Helper function to get API URL with proper protocol +const getApiUrl = () => { + if (typeof window !== 'undefined') { + const protocol = window.location.protocol.slice(0, -1) // Remove ':' from 'https:' + const host = window.location.hostname + return `${protocol}://${host}` + } + return `http://${process.env.NEXT_PUBLIC_BASE_URL || 'localhost'}` +} + interface User { id: string email: string @@ -84,7 +94,7 @@ export function AuthProvider({ children }: { children: ReactNode }) { const token = await tokenManager.getAccessToken() if (!token) return - const response = await fetch('/api-internal/v1/auth/me', { + const response = await fetch(`${getApiUrl()}/api-internal/v1/auth/me`, { headers: { 'Authorization': `Bearer ${token}`, }, @@ -114,7 +124,7 @@ export function AuthProvider({ children }: { children: ReactNode }) { setIsLoading(true) try { - const response = await fetch('/api-internal/v1/auth/login', { + const response = await fetch(`${getApiUrl()}/api-internal/v1/auth/login`, { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/frontend/src/lib/api-client.ts b/frontend/src/lib/api-client.ts index 75ae0aa..f08d5b2 100644 --- a/frontend/src/lib/api-client.ts +++ b/frontend/src/lib/api-client.ts @@ -1,10 +1,23 @@ import axios from 'axios'; import Cookies from 'js-cookie'; -const API_BASE_URL = process.env.NEXT_PUBLIC_BASE_URL || ''; +// Dynamic base URL with protocol detection +const getApiBaseUrl = (): string => { + if (typeof window !== 'undefined') { + // Client-side: use the same protocol as the current page + const protocol = window.location.protocol.slice(0, -1); // Remove ':' from 'https:' + const host = window.location.hostname; + return `${protocol}://${host}`; + } + + // Server-side: use environment variable or default to localhost + const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || 'localhost'; + const protocol = process.env.NODE_ENV === 'production' ? 'https' : 'http'; + return `${protocol}://${baseUrl}`; +}; const axiosInstance = axios.create({ - baseURL: API_BASE_URL, + baseURL: getApiBaseUrl(), headers: { 'Content-Type': 'application/json', }, @@ -36,7 +49,7 @@ axiosInstance.interceptors.response.use( try { const refreshToken = Cookies.get('refresh_token'); if (refreshToken) { - const response = await axios.post(`${API_BASE_URL}/api/auth/refresh`, { + const response = await axios.post(`${getApiBaseUrl()}/api/auth/refresh`, { refresh_token: refreshToken, }); diff --git a/frontend/src/lib/file-download.ts b/frontend/src/lib/file-download.ts index bb0ea2e..c0b9d48 100644 --- a/frontend/src/lib/file-download.ts +++ b/frontend/src/lib/file-download.ts @@ -76,12 +76,20 @@ export const downloadFileFromData = ( export const uploadFile = async ( file: File, url: string, - onProgress?: (progress: number) => void + onProgress?: (progress: number) => void, + additionalData?: Record ): Promise => { try { const formData = new FormData(); formData.append('file', file); + // Add additional form data if provided + if (additionalData) { + Object.entries(additionalData).forEach(([key, value]) => { + formData.append(key, value); + }); + } + const xhr = new XMLHttpRequest(); return new Promise((resolve, reject) => { From 3e55dc50c4c710034c0bd115d824e59e7be5eeeb Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Wed, 17 Sep 2025 10:57:44 +0200 Subject: [PATCH 21/43] rag fix --- frontend/package-lock.json | 105 ++++++++++++++++++++++++++++++ frontend/src/lib/file-download.ts | 11 ++++ 2 files changed, 116 insertions(+) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 2972dfa..9ef1bcd 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -7493,6 +7493,111 @@ "type": "github", "url": "https://github.com/sponsors/wooorm" } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.2.32", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.32.tgz", + "integrity": "sha512-osHXveM70zC+ilfuFa/2W6a1XQxJTvEhzEycnjUaVE8kpUS09lDpiDDX2YLdyFCzoUbvbo5r0X1Kp4MllIOShw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.32", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.32.tgz", + "integrity": "sha512-P9NpCAJuOiaHHpqtrCNncjqtSBi1f6QUdHK/+dNabBIXB2RUFWL19TY1Hkhu74OvyNQEYEzzMJCMQk5agjw1Qg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.32", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.32.tgz", + "integrity": "sha512-v7JaO0oXXt6d+cFjrrKqYnR2ubrD+JYP7nQVRZgeo5uNE5hkCpWnHmXm9vy3g6foMO8SPwL0P3MPw1c+BjbAzA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.32", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.32.tgz", + "integrity": "sha512-tA6sIKShXtSJBTH88i0DRd6I9n3ZTirmwpwAqH5zdJoQF7/wlJXR8DkPmKwYl5mFWhEKr5IIa3LfpMW9RRwKmQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.32", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.32.tgz", + "integrity": "sha512-rORQjXsAFeX6TLYJrCG5yoIDj+NKq31Rqwn8Wpn/bkPNy5rTHvOXkW8mLFonItS7QC6M+1JIIcLe+vOCTOYpvg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.32", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.32.tgz", + "integrity": "sha512-jHUeDPVHrgFltqoAqDB6g6OStNnFxnc7Aks3p0KE0FbwAvRg6qWKYF5mSTdCTxA3axoSAUwxYdILzXJfUwlHhA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.2.32", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.32.tgz", + "integrity": "sha512-2N0lSoU4GjfLSO50wvKpMQgKd4HdI2UHEhQPPPnlgfBJlOgJxkjpkYBqzk08f1gItBB6xF/n+ykso2hgxuydsA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } } } } diff --git a/frontend/src/lib/file-download.ts b/frontend/src/lib/file-download.ts index c0b9d48..bb6f0c0 100644 --- a/frontend/src/lib/file-download.ts +++ b/frontend/src/lib/file-download.ts @@ -1,3 +1,5 @@ +import Cookies from 'js-cookie'; + export const downloadFile = async (url: string, filename?: string): Promise => { try { const response = await fetch(url); @@ -117,7 +119,16 @@ export const uploadFile = async ( reject(new Error('Network error during upload')); }; + // Get authentication token from cookies + const token = Cookies.get('access_token'); + xhr.open('POST', url, true); + + // Set the authorization header if token exists + if (token) { + xhr.setRequestHeader('Authorization', `Bearer ${token}`); + } + xhr.send(formData); }); } catch (error) { From bd7b2348ce0454e51d743e0a2147951f0e043392 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Wed, 17 Sep 2025 11:58:23 +0200 Subject: [PATCH 22/43] toast fix --- .github/workflows/build-all.yml | 4 +- frontend/src/app/layout.tsx | 17 +-- frontend/src/contexts/ToastContext.tsx | 150 +++++++++++++++++++++++++ 3 files changed, 161 insertions(+), 10 deletions(-) create mode 100644 frontend/src/contexts/ToastContext.tsx diff --git a/.github/workflows/build-all.yml b/.github/workflows/build-all.yml index 045d344..b99bda3 100644 --- a/.github/workflows/build-all.yml +++ b/.github/workflows/build-all.yml @@ -2,10 +2,8 @@ name: Build All Docker Images on: push: - branches: [ main, develop ] tags: [ 'v*' ] - pull_request: - branches: [ main ] + env: REGISTRY: ghcr.io diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index e0f3c58..f6b4fa1 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -7,6 +7,7 @@ import { Toaster as HotToaster } from 'react-hot-toast' import { AuthProvider } from '@/contexts/AuthContext' import { ModulesProvider } from '@/contexts/ModulesContext' import { PluginProvider } from '@/contexts/PluginContext' +import { ToastProvider } from '@/contexts/ToastContext' import { Navigation } from '@/components/ui/navigation' const inter = Inter({ subsets: ['latin'] }) @@ -68,13 +69,15 @@ export default function RootLayout({ -
- -
- {children} -
-
- + +
+ +
+ {children} +
+
+ +
diff --git a/frontend/src/contexts/ToastContext.tsx b/frontend/src/contexts/ToastContext.tsx new file mode 100644 index 0000000..81a2b3c --- /dev/null +++ b/frontend/src/contexts/ToastContext.tsx @@ -0,0 +1,150 @@ +"use client" + +import React, { createContext, useContext, useState, useCallback, useRef } from 'react' +import { generateShortId } from '@/lib/id-utils' + +export interface ToastProps { + id: string + title?: string + description?: string + variant?: 'default' | 'destructive' | 'success' | 'warning' + action?: React.ReactElement + duration?: number +} + +export interface ToastOptions extends Omit { + duration?: number +} + +interface ToastContextType { + toasts: ToastProps[] + toast: (options: ToastOptions) => () => void + success: (title: string, description?: string, options?: Partial) => () => void + error: (title: string, description?: string, options?: Partial) => () => void + warning: (title: string, description?: string, options?: Partial) => () => void + info: (title: string, description?: string, options?: Partial) => () => void + dismiss: (id: string) => void + clearAll: () => void +} + +const ToastContext = createContext(undefined) + +export function ToastProvider({ children }: { children: React.ReactNode }) { + const [toasts, setToasts] = useState([]) + const timeoutRefs = useRef>(new Map()) + + const dismissToast = useCallback((id: string) => { + setToasts(prev => prev.filter(toast => toast.id !== id)) + + // Clear timeout if exists + const timeoutId = timeoutRefs.current.get(id) + if (timeoutId) { + clearTimeout(timeoutId) + timeoutRefs.current.delete(id) + } + }, []) + + const toast = useCallback((options: ToastOptions) => { + const { + duration = 5000, + variant = 'default', + ...props + } = options + + // Generate unique ID using improved utility + const id = generateShortId('toast') + const toastWithId: ToastProps = { + ...props, + id, + variant, + duration + } + + // Add to toasts array + setToasts(prev => [...prev, toastWithId]) + + // Auto-remove after specified duration + if (duration > 0) { + const timeoutId = setTimeout(() => { + dismissToast(id) + }, duration) + + timeoutRefs.current.set(id, timeoutId) + } + + // Return dismiss function for manual control + return () => dismissToast(id) + }, [dismissToast]) + + // Convenience methods for common toast types + const success = useCallback((title: string, description?: string, options?: Partial) => { + return toast({ + title, + description, + variant: 'success', + ...options + }) + }, [toast]) + + const error = useCallback((title: string, description?: string, options?: Partial) => { + return toast({ + title, + description, + variant: 'destructive', + duration: 7000, // Errors should stay longer + ...options + }) + }, [toast]) + + const warning = useCallback((title: string, description?: string, options?: Partial) => { + return toast({ + title, + description, + variant: 'warning', + ...options + }) + }, [toast]) + + const info = useCallback((title: string, description?: string, options?: Partial) => { + return toast({ + title, + description, + variant: 'default', + ...options + }) + }, [toast]) + + // Clear all toasts + const clearAll = useCallback(() => { + // Clear all timeouts + timeoutRefs.current.forEach(timeoutId => clearTimeout(timeoutId)) + timeoutRefs.current.clear() + + setToasts([]) + }, []) + + const value: ToastContextType = { + toasts, + toast, + success, + error, + warning, + info, + dismiss: dismissToast, + clearAll, + } + + return ( + + {children} + + ) +} + +export function useToast() { + const context = useContext(ToastContext) + if (context === undefined) { + throw new Error('useToast must be used within a ToastProvider') + } + return context +} \ No newline at end of file From 49a2b9f09b3800718887ec688b01fc0bd9cd7e7d Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Wed, 17 Sep 2025 12:33:50 +0200 Subject: [PATCH 23/43] errors --- .../src/components/chatbot/ChatInterface.tsx | 44 ++++++++++++++----- frontend/src/hooks/use-chatbot-form.ts | 29 +++++++----- frontend/src/lib/api-client.ts | 2 +- 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/frontend/src/components/chatbot/ChatInterface.tsx b/frontend/src/components/chatbot/ChatInterface.tsx index fb65658..167a712 100644 --- a/frontend/src/components/chatbot/ChatInterface.tsx +++ b/frontend/src/components/chatbot/ChatInterface.tsx @@ -11,7 +11,7 @@ import { Separator } from "@/components/ui/separator" import { MessageCircle, Send, Bot, User, Loader2, Copy, ThumbsUp, ThumbsDown } from "lucide-react" import { useToast } from "@/hooks/use-toast" import { generateTimestampId } from "@/lib/id-utils" -import { chatbotApi, type AppError } from "@/lib/api-client" +import { chatbotApi } from "@/lib/api-client" import ReactMarkdown from "react-markdown" import remarkGfm from "remark-gfm" import rehypeHighlight from "rehype-highlight" @@ -126,11 +126,10 @@ export function ChatInterface({ chatbotId, chatbotName, onClose }: ChatInterface content: msg.content })) - const data = await chatbotApi.sendMessage( + const data = await chatbotApi.chat( chatbotId, messageToSend, - conversationId || undefined, - conversationHistory + { conversation_id: conversationId || undefined } ) // Update conversation ID if it's a new conversation @@ -149,15 +148,36 @@ export function ChatInterface({ chatbotId, chatbotName, onClose }: ChatInterface setMessages(prev => [...prev, assistantMessage]) } catch (error) { - const appError = error as AppError - - // More specific error handling - if (appError.code === 'UNAUTHORIZED') { - toast.error("Authentication Required", "Please log in to continue chatting.") - } else if (appError.code === 'NETWORK_ERROR') { - toast.error("Connection Error", "Please check your internet connection and try again.") + console.error('Chat error:', error) + + // Handle different error types + if (error && typeof error === 'object') { + if ('response' in error) { + // Axios error + const status = error.response?.status + if (status === 401) { + toast.error("Authentication Required", "Please log in to continue chatting.") + } else if (status === 429) { + toast.error("Rate Limit", "Too many requests. Please wait and try again.") + } else { + toast.error("Message Failed", error.response?.data?.detail || "Failed to send message. Please try again.") + } + } else if ('code' in error) { + // Custom error with code + if (error.code === 'UNAUTHORIZED') { + toast.error("Authentication Required", "Please log in to continue chatting.") + } else if (error.code === 'NETWORK_ERROR') { + toast.error("Connection Error", "Please check your internet connection and try again.") + } else { + toast.error("Message Failed", error.message || "Failed to send message. Please try again.") + } + } else { + // Generic error + toast.error("Message Failed", error.message || "Failed to send message. Please try again.") + } } else { - toast.error("Message Failed", appError.message || "Failed to send message. Please try again.") + // Fallback for unknown error types + toast.error("Message Failed", "An unexpected error occurred. Please try again.") } } finally { setIsLoading(false) diff --git a/frontend/src/hooks/use-chatbot-form.ts b/frontend/src/hooks/use-chatbot-form.ts index 87d901d..5890451 100644 --- a/frontend/src/hooks/use-chatbot-form.ts +++ b/frontend/src/hooks/use-chatbot-form.ts @@ -4,7 +4,7 @@ import { useState, useCallback, useMemo } from 'react' import { generateId } from '@/lib/id-utils' -import { chatbotApi, type AppError } from '@/lib/api-client' +import { chatbotApi } from '@/lib/api-client' import { useToast } from './use-toast' export interface ChatbotConfig { @@ -59,10 +59,10 @@ export function useChatbotForm() { const loadChatbots = useCallback(async () => { setIsLoading(true) try { - const data = await chatbotApi.listChatbots() + const data = await chatbotApi.list() setChatbots(data) } catch (error) { - const appError = error as AppError + console.error('Load chatbots error:', error) toast.error("Loading Failed", "Failed to load chatbots") } finally { setIsLoading(false) @@ -73,15 +73,20 @@ export function useChatbotForm() { const createChatbot = useCallback(async (config: ChatbotConfig) => { setIsSubmitting(true) try { - const newChatbot = await chatbotApi.createChatbot(config) + const newChatbot = await chatbotApi.create(config) setChatbots(prev => [...prev, newChatbot]) toast.success("Success", `Chatbot "${config.name}" created successfully`) return newChatbot } catch (error) { - const appError = error as AppError - - if (appError.code === 'VALIDATION_ERROR') { - toast.error("Validation Error", appError.details || "Please check your input") + console.error('Create chatbot error:', error) + + if (error && typeof error === 'object' && 'response' in error) { + const detail = error.response?.data?.detail || error.response?.data?.error + if (detail) { + toast.error("Validation Error", detail) + } else { + toast.error("Creation Failed", "Failed to create chatbot") + } } else { toast.error("Creation Failed", "Failed to create chatbot") } @@ -95,12 +100,12 @@ export function useChatbotForm() { const updateChatbot = useCallback(async (id: string, config: ChatbotConfig) => { setIsSubmitting(true) try { - const updatedChatbot = await chatbotApi.updateChatbot(id, config) + const updatedChatbot = await chatbotApi.update(id, config) setChatbots(prev => prev.map(bot => bot.id === id ? updatedChatbot : bot)) toast.success("Success", `Chatbot "${config.name}" updated successfully`) return updatedChatbot } catch (error) { - const appError = error as AppError + console.error('Update chatbot error:', error) toast.error("Update Failed", "Failed to update chatbot") throw error } finally { @@ -112,11 +117,11 @@ export function useChatbotForm() { const deleteChatbot = useCallback(async (id: string) => { setIsSubmitting(true) try { - await chatbotApi.deleteChatbot(id) + await chatbotApi.delete(id) setChatbots(prev => prev.filter(bot => bot.id !== id)) toast.success("Success", "Chatbot deleted successfully") } catch (error) { - const appError = error as AppError + console.error('Delete chatbot error:', error) toast.error("Deletion Failed", "Failed to delete chatbot") throw error } finally { diff --git a/frontend/src/lib/api-client.ts b/frontend/src/lib/api-client.ts index f08d5b2..1c03d16 100644 --- a/frontend/src/lib/api-client.ts +++ b/frontend/src/lib/api-client.ts @@ -106,5 +106,5 @@ export const chatbotApi = { update: async (id: string, data: any) => apiClient.put(`/api/chatbot/update/${id}`, data), delete: async (id: string) => apiClient.delete(`/api/chatbot/delete/${id}`), chat: async (id: string, message: string, config?: any) => - apiClient.post(`/api/chatbot/chat`, { chatbot_id: id, message, ...config }), + apiClient.post(`/api/chatbot/chat/${id}`, { message, ...config }), }; \ No newline at end of file From 02228fe734d5db54bd489d82c2dfcfbff395b036 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Wed, 17 Sep 2025 12:53:31 +0200 Subject: [PATCH 24/43] chatbot internal endpoint fix --- frontend/package-lock.json | 210 +++++++++--------- .../src/components/chatbot/ChatInterface.tsx | 9 +- frontend/src/lib/api-client.ts | 23 +- 3 files changed, 127 insertions(+), 115 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 9ef1bcd..0738b71 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -279,6 +279,66 @@ "glob": "7.1.7" } }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.2.32", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.32.tgz", + "integrity": "sha512-osHXveM70zC+ilfuFa/2W6a1XQxJTvEhzEycnjUaVE8kpUS09lDpiDDX2YLdyFCzoUbvbo5r0X1Kp4MllIOShw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.32", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.32.tgz", + "integrity": "sha512-P9NpCAJuOiaHHpqtrCNncjqtSBi1f6QUdHK/+dNabBIXB2RUFWL19TY1Hkhu74OvyNQEYEzzMJCMQk5agjw1Qg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.32", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.32.tgz", + "integrity": "sha512-v7JaO0oXXt6d+cFjrrKqYnR2ubrD+JYP7nQVRZgeo5uNE5hkCpWnHmXm9vy3g6foMO8SPwL0P3MPw1c+BjbAzA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.32", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.32.tgz", + "integrity": "sha512-tA6sIKShXtSJBTH88i0DRd6I9n3ZTirmwpwAqH5zdJoQF7/wlJXR8DkPmKwYl5mFWhEKr5IIa3LfpMW9RRwKmQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@next/swc-linux-x64-gnu": { "version": "14.2.32", "cpu": [ @@ -307,6 +367,51 @@ "node": ">= 10" } }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.32", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.32.tgz", + "integrity": "sha512-rORQjXsAFeX6TLYJrCG5yoIDj+NKq31Rqwn8Wpn/bkPNy5rTHvOXkW8mLFonItS7QC6M+1JIIcLe+vOCTOYpvg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.32", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.32.tgz", + "integrity": "sha512-jHUeDPVHrgFltqoAqDB6g6OStNnFxnc7Aks3p0KE0FbwAvRg6qWKYF5mSTdCTxA3axoSAUwxYdILzXJfUwlHhA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.2.32", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.32.tgz", + "integrity": "sha512-2N0lSoU4GjfLSO50wvKpMQgKd4HdI2UHEhQPPPnlgfBJlOgJxkjpkYBqzk08f1gItBB6xF/n+ykso2hgxuydsA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "license": "MIT", @@ -7493,111 +7598,6 @@ "type": "github", "url": "https://github.com/sponsors/wooorm" } - }, - "node_modules/@next/swc-darwin-arm64": { - "version": "14.2.32", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.32.tgz", - "integrity": "sha512-osHXveM70zC+ilfuFa/2W6a1XQxJTvEhzEycnjUaVE8kpUS09lDpiDDX2YLdyFCzoUbvbo5r0X1Kp4MllIOShw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-darwin-x64": { - "version": "14.2.32", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.32.tgz", - "integrity": "sha512-P9NpCAJuOiaHHpqtrCNncjqtSBi1f6QUdHK/+dNabBIXB2RUFWL19TY1Hkhu74OvyNQEYEzzMJCMQk5agjw1Qg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.2.32", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.32.tgz", - "integrity": "sha512-v7JaO0oXXt6d+cFjrrKqYnR2ubrD+JYP7nQVRZgeo5uNE5hkCpWnHmXm9vy3g6foMO8SPwL0P3MPw1c+BjbAzA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.2.32", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.32.tgz", - "integrity": "sha512-tA6sIKShXtSJBTH88i0DRd6I9n3ZTirmwpwAqH5zdJoQF7/wlJXR8DkPmKwYl5mFWhEKr5IIa3LfpMW9RRwKmQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.2.32", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.32.tgz", - "integrity": "sha512-rORQjXsAFeX6TLYJrCG5yoIDj+NKq31Rqwn8Wpn/bkPNy5rTHvOXkW8mLFonItS7QC6M+1JIIcLe+vOCTOYpvg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.2.32", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.32.tgz", - "integrity": "sha512-jHUeDPVHrgFltqoAqDB6g6OStNnFxnc7Aks3p0KE0FbwAvRg6qWKYF5mSTdCTxA3axoSAUwxYdILzXJfUwlHhA==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.2.32", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.32.tgz", - "integrity": "sha512-2N0lSoU4GjfLSO50wvKpMQgKd4HdI2UHEhQPPPnlgfBJlOgJxkjpkYBqzk08f1gItBB6xF/n+ykso2hgxuydsA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } } } } diff --git a/frontend/src/components/chatbot/ChatInterface.tsx b/frontend/src/components/chatbot/ChatInterface.tsx index 167a712..b365ca6 100644 --- a/frontend/src/components/chatbot/ChatInterface.tsx +++ b/frontend/src/components/chatbot/ChatInterface.tsx @@ -129,7 +129,10 @@ export function ChatInterface({ chatbotId, chatbotName, onClose }: ChatInterface const data = await chatbotApi.chat( chatbotId, messageToSend, - { conversation_id: conversationId || undefined } + { + messages: conversationHistory, + conversation_id: conversationId || undefined + } ) // Update conversation ID if it's a new conversation @@ -138,9 +141,9 @@ export function ChatInterface({ chatbotId, chatbotName, onClose }: ChatInterface } const assistantMessage: ChatMessage = { - id: data.message_id || generateTimestampId('msg'), + id: data.id || generateTimestampId('msg'), role: 'assistant', - content: data.response, + content: data.choices?.[0]?.message?.content || data.response || 'No response', timestamp: new Date(), sources: data.sources } diff --git a/frontend/src/lib/api-client.ts b/frontend/src/lib/api-client.ts index 1c03d16..86c4c52 100644 --- a/frontend/src/lib/api-client.ts +++ b/frontend/src/lib/api-client.ts @@ -49,7 +49,7 @@ axiosInstance.interceptors.response.use( try { const refreshToken = Cookies.get('refresh_token'); if (refreshToken) { - const response = await axios.post(`${getApiBaseUrl()}/api/auth/refresh`, { + const response = await axios.post(`${getApiBaseUrl()}/api-internal/v1/auth/refresh`, { refresh_token: refreshToken, }); @@ -101,10 +101,19 @@ export const apiClient = { // Chatbot specific API methods export const chatbotApi = { - create: async (data: any) => apiClient.post('/api/chatbot/create', data), - list: async () => apiClient.get('/api/chatbot/list'), - update: async (id: string, data: any) => apiClient.put(`/api/chatbot/update/${id}`, data), - delete: async (id: string) => apiClient.delete(`/api/chatbot/delete/${id}`), - chat: async (id: string, message: string, config?: any) => - apiClient.post(`/api/chatbot/chat/${id}`, { message, ...config }), + create: async (data: any) => apiClient.post('/api-internal/v1/chatbot/create', data), + list: async () => apiClient.get('/api-internal/v1/chatbot/list'), + update: async (id: string, data: any) => apiClient.put(`/api-internal/v1/chatbot/update/${id}`, data), + delete: async (id: string) => apiClient.delete(`/api-internal/v1/chatbot/delete/${id}`), + chat: async (id: string, message: string, config?: any) => { + // For OpenAI-compatible chat completions + const messages = [ + ...(config?.messages || []), + { role: 'user', content: message } + ] + return apiClient.post(`/api-internal/v1/chatbot/${id}/chat/completions`, { + messages, + ...config + }) + }, }; \ No newline at end of file From c5dc8898376b7a556e0ef3a16ffdb89ecd4de677 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Wed, 17 Sep 2025 13:32:18 +0200 Subject: [PATCH 25/43] remove security blocking --- backend/app/services/llm/models.py | 21 ++-- backend/app/services/llm/service.py | 183 ++++------------------------ 2 files changed, 33 insertions(+), 171 deletions(-) diff --git a/backend/app/services/llm/models.py b/backend/app/services/llm/models.py index 903451d..888a3cc 100644 --- a/backend/app/services/llm/models.py +++ b/backend/app/services/llm/models.py @@ -71,11 +71,11 @@ class ChatResponse(BaseModel): usage: Optional[TokenUsage] = Field(None, description="Token usage") system_fingerprint: Optional[str] = Field(None, description="System fingerprint") - # Security and audit information - security_check: bool = Field(..., description="Whether security check passed") - risk_score: float = Field(..., description="Security risk score") - detected_patterns: List[str] = Field(default_factory=list, description="Detected security patterns") - + # Security fields maintained for backward compatibility + security_check: Optional[bool] = Field(None, description="Whether security check passed") + risk_score: Optional[float] = Field(None, description="Security risk score") + detected_patterns: Optional[List[str]] = Field(None, description="Detected security patterns") + # Performance metrics latency_ms: Optional[float] = Field(None, description="Response latency in milliseconds") provider_latency_ms: Optional[float] = Field(None, description="Provider-specific latency") @@ -117,10 +117,11 @@ class EmbeddingResponse(BaseModel): provider: str = Field(..., description="Provider used") usage: Optional[TokenUsage] = Field(None, description="Token usage") - # Security and audit information - security_check: bool = Field(..., description="Whether security check passed") - risk_score: float = Field(..., description="Security risk score") - + # Security fields maintained for backward compatibility + security_check: Optional[bool] = Field(None, description="Whether security check passed") + risk_score: Optional[float] = Field(None, description="Security risk score") + detected_patterns: Optional[List[str]] = Field(None, description="Detected security patterns") + # Performance metrics latency_ms: Optional[float] = Field(None, description="Response latency in milliseconds") provider_latency_ms: Optional[float] = Field(None, description="Provider-specific latency") @@ -157,9 +158,7 @@ class LLMMetrics(BaseModel): total_requests: int = Field(0, description="Total requests processed") successful_requests: int = Field(0, description="Successful requests") failed_requests: int = Field(0, description="Failed requests") - security_blocked_requests: int = Field(0, description="Security blocked requests") average_latency_ms: float = Field(0.0, description="Average response latency") - average_risk_score: float = Field(0.0, description="Average security risk score") provider_metrics: Dict[str, Dict[str, Any]] = Field(default_factory=dict, description="Per-provider metrics") last_updated: datetime = Field(default_factory=datetime.utcnow, description="Last metrics update") diff --git a/backend/app/services/llm/service.py b/backend/app/services/llm/service.py index fae28fd..a764bf3 100644 --- a/backend/app/services/llm/service.py +++ b/backend/app/services/llm/service.py @@ -16,7 +16,7 @@ from .models import ( ModelInfo, ProviderStatus, LLMMetrics ) from .config import config_manager, ProviderConfig -from .security import security_manager +# Security service removed as requested from .resilience import ResilienceManagerFactory from .metrics import metrics_collector from .providers import BaseLLMProvider, PrivateModeProvider @@ -149,53 +149,8 @@ class LLMService: if not request.messages: raise ValidationError("Messages cannot be empty", field="messages") - # Security validation - # Chatbot and RAG system requests should have relaxed security validation - is_system_request = ( - request.user_id == "rag_system" or - request.user_id == "chatbot_user" or - str(request.user_id).startswith("chatbot_") - ) - + # Security validation removed as requested messages_dict = [{"role": msg.role, "content": msg.content} for msg in request.messages] - is_safe, risk_score, detected_patterns = security_manager.validate_prompt_security(messages_dict) - - if not is_safe and not is_system_request: - # Log security violation for regular user requests - security_manager.create_audit_log( - user_id=request.user_id, - api_key_id=request.api_key_id, - provider="blocked", - model=request.model, - request_type="chat_completion", - risk_score=risk_score, - detected_patterns=[p.get("pattern", "") for p in detected_patterns] - ) - - # Record blocked request - metrics_collector.record_request( - provider="security", - model=request.model, - request_type="chat_completion", - success=False, - latency_ms=0, - security_risk_score=risk_score, - error_code="SECURITY_BLOCKED", - user_id=request.user_id, - api_key_id=request.api_key_id - ) - - raise SecurityError( - "Request blocked due to security concerns", - risk_score=risk_score, - details={"detected_patterns": detected_patterns} - ) - elif not is_safe and is_system_request: - # For system requests (chatbot/RAG), log but don't block - logger.info(f"System request contains security patterns (risk_score={risk_score:.2f}) but allowing due to system context") - if detected_patterns: - logger.info(f"Detected patterns: {[p.get('pattern', 'unknown') for p in detected_patterns]}") - # Allow system requests regardless of security patterns # Get provider for model provider_name = self._get_provider_for_model(request.model) @@ -204,18 +159,7 @@ class LLMService: if not provider: raise ProviderError(f"No available provider for model '{request.model}'", provider=provider_name) - # Log detailed request if enabled - security_manager.log_detailed_request( - messages=messages_dict, - model=request.model, - user_id=request.user_id, - provider=provider_name, - context_info={ - "temperature": request.temperature, - "max_tokens": request.max_tokens, - "risk_score": f"{risk_score:.3f}" - } - ) + # Security logging removed as requested # Execute with resilience resilience_manager = ResilienceManagerFactory.get_manager(provider_name) @@ -226,22 +170,15 @@ class LLMService: provider.create_chat_completion, request, retryable_exceptions=(ProviderError, TimeoutError), - non_retryable_exceptions=(SecurityError, ValidationError) + non_retryable_exceptions=(ValidationError,) ) - # Update response with security information - response.security_check = is_safe - response.risk_score = risk_score - response.detected_patterns = [p.get("pattern", "") for p in detected_patterns] + # Set default security values since security is removed + response.security_check = True + response.risk_score = 0.0 + response.detected_patterns = [] - # Log detailed response if enabled - if response.choices: - content = response.choices[0].message.content - security_manager.log_detailed_response( - response_content=content, - token_usage=response.usage.model_dump() if response.usage else None, - provider=provider_name - ) + # Security logging removed as requested # Record successful request total_latency = (time.time() - start_time) * 1000 @@ -252,26 +189,12 @@ class LLMService: success=True, latency_ms=total_latency, token_usage=response.usage.model_dump() if response.usage else None, - security_risk_score=risk_score, + # security_risk_score removed as requested user_id=request.user_id, api_key_id=request.api_key_id ) - # Create audit log - security_manager.create_audit_log( - user_id=request.user_id, - api_key_id=request.api_key_id, - provider=provider_name, - model=request.model, - request_type="chat_completion", - risk_score=risk_score, - detected_patterns=[p.get("pattern", "") for p in detected_patterns], - metadata={ - "success": True, - "latency_ms": total_latency, - "token_usage": response.usage.model_dump() if response.usage else None - } - ) + # Security audit logging removed as requested return response @@ -286,28 +209,13 @@ class LLMService: request_type="chat_completion", success=False, latency_ms=total_latency, - security_risk_score=risk_score, + # security_risk_score removed as requested error_code=error_code, user_id=request.user_id, api_key_id=request.api_key_id ) - # Create audit log for failure - security_manager.create_audit_log( - user_id=request.user_id, - api_key_id=request.api_key_id, - provider=provider_name, - model=request.model, - request_type="chat_completion", - risk_score=risk_score, - detected_patterns=[p.get("pattern", "") for p in detected_patterns], - metadata={ - "success": False, - "error": str(e), - "error_code": error_code, - "latency_ms": total_latency - } - ) + # Security audit logging removed as requested raise @@ -316,26 +224,8 @@ class LLMService: if not self._initialized: await self.initialize() - # Security validation (same as non-streaming) - # Chatbot and RAG system requests should have relaxed security validation - is_system_request = ( - request.user_id == "rag_system" or - request.user_id == "chatbot_user" or - str(request.user_id).startswith("chatbot_") - ) - + # Security validation removed as requested messages_dict = [{"role": msg.role, "content": msg.content} for msg in request.messages] - is_safe, risk_score, detected_patterns = security_manager.validate_prompt_security(messages_dict) - - if not is_safe and not is_system_request: - raise SecurityError( - "Streaming request blocked due to security concerns", - risk_score=risk_score, - details={"detected_patterns": detected_patterns} - ) - elif not is_safe and is_system_request: - # For system requests (chatbot/RAG), log but don't block - logger.info(f"System streaming request contains security patterns (risk_score={risk_score:.2f}) but allowing due to system context") # Get provider provider_name = self._get_provider_for_model(request.model) @@ -352,7 +242,7 @@ class LLMService: provider.create_chat_completion_stream, request, retryable_exceptions=(ProviderError, TimeoutError), - non_retryable_exceptions=(SecurityError, ValidationError) + non_retryable_exceptions=(ValidationError,) ): yield chunk @@ -365,7 +255,7 @@ class LLMService: request_type="chat_completion_stream", success=False, latency_ms=0, - security_risk_score=risk_score, + # security_risk_score removed as requested error_code=error_code, user_id=request.user_id, api_key_id=request.api_key_id @@ -377,34 +267,7 @@ class LLMService: if not self._initialized: await self.initialize() - # Security validation for embedding input - # RAG system requests (document embedding) should use relaxed security validation - is_rag_system = request.user_id == "rag_system" - - if not is_rag_system: - # Apply normal security validation for user-generated embedding requests - input_text = request.input if isinstance(request.input, str) else " ".join(request.input) - is_safe, risk_score, detected_patterns = security_manager.validate_prompt_security([ - {"role": "user", "content": input_text} - ]) - - if not is_safe: - raise SecurityError( - "Embedding request blocked due to security concerns", - risk_score=risk_score, - details={"detected_patterns": detected_patterns} - ) - else: - # For RAG system requests, log but don't block (document content can contain legitimate text that triggers patterns) - input_text = request.input if isinstance(request.input, str) else " ".join(request.input) - is_safe, risk_score, detected_patterns = security_manager.validate_prompt_security([ - {"role": "user", "content": input_text} - ]) - - if detected_patterns: - logger.info(f"RAG document embedding contains security patterns (risk_score={risk_score:.2f}) but allowing due to document context") - - # Allow RAG system requests regardless of security patterns + # Security validation removed as requested # Get provider provider_name = self._get_provider_for_model(request.model) @@ -422,12 +285,12 @@ class LLMService: provider.create_embedding, request, retryable_exceptions=(ProviderError, TimeoutError), - non_retryable_exceptions=(SecurityError, ValidationError) + non_retryable_exceptions=(ValidationError,) ) - # Update response with security information - response.security_check = is_safe - response.risk_score = risk_score + # Set default security values since security is removed + response.security_check = True + response.risk_score = 0.0 # Record successful request total_latency = (time.time() - start_time) * 1000 @@ -438,7 +301,7 @@ class LLMService: success=True, latency_ms=total_latency, token_usage=response.usage.model_dump() if response.usage else None, - security_risk_score=risk_score, + # security_risk_score removed as requested user_id=request.user_id, api_key_id=request.api_key_id ) @@ -456,7 +319,7 @@ class LLMService: request_type="embedding", success=False, latency_ms=total_latency, - security_risk_score=risk_score, + # security_risk_score removed as requested error_code=error_code, user_id=request.user_id, api_key_id=request.api_key_id From af0fc270892ad50df13f18e04eddfef425c26cd3 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Wed, 17 Sep 2025 14:44:23 +0200 Subject: [PATCH 26/43] chatbot fix --- frontend/src/app/settings/page.tsx | 352 ++--------------------------- 1 file changed, 17 insertions(+), 335 deletions(-) diff --git a/frontend/src/app/settings/page.tsx b/frontend/src/app/settings/page.tsx index 9af3f19..796ffde 100644 --- a/frontend/src/app/settings/page.tsx +++ b/frontend/src/app/settings/page.tsx @@ -11,11 +11,10 @@ import { Textarea } from "@/components/ui/textarea"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Alert, AlertDescription } from "@/components/ui/alert"; -import { - Settings, - Save, +import { + Settings, + Save, RefreshCw, - Shield, Globe, Database, Mail, @@ -36,30 +35,9 @@ import { useModules, triggerModuleRefresh } from '@/contexts/ModulesContext'; import { Badge } from '@/components/ui/badge'; interface SystemSettings { - // Security Settings - security: { - password_min_length: number; - password_require_uppercase: boolean; - password_require_lowercase: boolean; - password_require_numbers: boolean; - password_require_symbols: boolean; - session_timeout_minutes: number; - max_login_attempts: number; - lockout_duration_minutes: number; - require_2fa: boolean; - allowed_domains: string[]; - }; // API Settings api: { - // Security Settings - security_enabled: boolean; - threat_detection_enabled: boolean; - rate_limiting_enabled: boolean; - ip_reputation_enabled: boolean; - anomaly_detection_enabled: boolean; - security_headers_enabled: boolean; - // Rate Limiting by Authentication Level rate_limit_authenticated_per_minute: number; rate_limit_authenticated_per_hour: number; @@ -67,23 +45,13 @@ interface SystemSettings { rate_limit_api_key_per_hour: number; rate_limit_premium_per_minute: number; rate_limit_premium_per_hour: number; - - // Security Thresholds - security_risk_threshold: number; - security_warning_threshold: number; - anomaly_threshold: number; - + // Request Settings max_request_size_mb: number; max_request_size_premium_mb: number; enable_cors: boolean; cors_origins: string[]; api_key_expiry_days: number; - - // IP Security - blocked_ips: string[]; - allowed_ips: string[]; - csp_header: string; }; // Notification Settings @@ -95,7 +63,6 @@ interface SystemSettings { smtp_use_tls: boolean; from_address: string; budget_alerts: boolean; - security_alerts: boolean; system_alerts: boolean; }; } @@ -180,13 +147,16 @@ function SettingsPageContent() { // Transform backend format to frontend format const transformedSettings = {} as SystemSettings; - - // Transform each category from backend format {key: {value, type, description}} + + // Transform each category from backend format {key: {value, type, description}} // to frontend format {key: value} + // Skip security category as it has been removed from the UI for (const [categoryName, categorySettings] of Object.entries(data)) { + if (categoryName === 'security') continue; // Skip security settings + if (typeof categorySettings === 'object' && categorySettings !== null) { transformedSettings[categoryName as keyof SystemSettings] = {} as any; - + for (const [key, setting] of Object.entries(categorySettings as any)) { if (typeof setting === 'object' && setting !== null && 'value' in setting) { transformedSettings[categoryName as keyof SystemSettings][key] = setting.value; @@ -384,214 +354,27 @@ function SettingsPageContent() { )} - - - Security + + API Notifications Modules - - - - - - Security Settings - - - Configure password policies, session management, and authentication settings - - - -
-
-

Password Policy

-
-
- - updateSetting("security", "password_min_length", parseInt(e.target.value))} - /> -
-
-
- updateSetting("security", "password_require_uppercase", checked)} - /> - -
-
- updateSetting("security", "password_require_lowercase", checked)} - /> - -
-
- updateSetting("security", "password_require_numbers", checked)} - /> - -
-
- updateSetting("security", "password_require_symbols", checked)} - /> - -
-
-
-
- -
-

Session & Authentication

-
-
- - updateSetting("security", "session_timeout_minutes", parseInt(e.target.value))} - /> -
-
- - updateSetting("security", "max_login_attempts", parseInt(e.target.value))} - /> -
-
- - updateSetting("security", "lockout_duration_minutes", parseInt(e.target.value))} - /> -
-
- updateSetting("security", "require_2fa", checked)} - /> - -
-
-
-
- -
- -