diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d9c412d4..7beef5866 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -82,6 +82,24 @@ All notable changes to Bambuddy will be documented in this file. - Bulk edit: printer assignment, print options, queue options - Bulk cancel selected items - Tri-state toggles: unchanged / on / off for each setting +- **Model-Based Queue Assignment** - Queue prints to "any printer of matching model" for load balancing (Issue #162): + - Extract printer model from sliced 3MF files (e.g., "X1C", "P1S") + - Display sliced-for model in archive view + - New queue mode: assign to model instead of specific printer + - Scheduler auto-assigns to first idle printer of matching model + - Filament validation: only assign to printers with required filament types loaded + - Waiting reason display: shows why jobs are waiting (e.g., "Waiting for filament: Printer1 (needs PLA)") + - "Waiting" status badge (purple) distinguishes from regular "Pending" + - Compatibility warnings when file/printer model mismatch +- **Queue Notifications** - Get notified about print queue events: + - Job Added: When a job is added to the queue + - Job Assigned: When a model-based job is assigned to a printer + - Job Started: When a queue job starts printing + - Job Waiting: When a job is waiting for filament (enabled by default) + - Job Skipped: When a job is skipped due to previous failure (enabled by default) + - Job Failed: When a job fails to start (enabled by default) + - Queue Complete: When all queued jobs finish + - New "Print Queue" section in notification provider settings ### Fixes - **HMS Error Notifications** - Get notified when printer errors occur (Issue #84): diff --git a/README.md b/README.md index 289b5af18..230b20908 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,8 @@ ### ⏰ Scheduling & Automation - Print queue with drag-and-drop - Multi-printer selection (send to multiple printers at once) +- Model-based queue assignment (send to "any X1C" for load balancing) +- Filament validation (only assign to printers with required filaments) - Per-printer AMS mapping (individual slot configuration for print farms) - Scheduled prints (date/time) - Queue Only mode (stage without auto-start) @@ -115,6 +117,7 @@ - Print finish photo URL in notifications - HMS error alerts (AMS, nozzle, etc.) - Build plate detection alerts +- Queue events (waiting, skipped, failed) ### 🔧 Integrations - [Spoolman](https://github.com/Donkie/Spoolman) filament sync diff --git a/backend/app/api/routes/notifications.py b/backend/app/api/routes/notifications.py index a6c925719..f94ce1431 100644 --- a/backend/app/api/routes/notifications.py +++ b/backend/app/api/routes/notifications.py @@ -53,6 +53,14 @@ def _provider_to_dict(provider: NotificationProvider) -> dict: "on_ams_ht_temperature_high": provider.on_ams_ht_temperature_high, # Build plate detection "on_plate_not_empty": provider.on_plate_not_empty, + # Print queue events + "on_queue_job_added": provider.on_queue_job_added, + "on_queue_job_assigned": provider.on_queue_job_assigned, + "on_queue_job_started": provider.on_queue_job_started, + "on_queue_job_waiting": provider.on_queue_job_waiting, + "on_queue_job_skipped": provider.on_queue_job_skipped, + "on_queue_job_failed": provider.on_queue_job_failed, + "on_queue_completed": provider.on_queue_completed, # Quiet hours "quiet_hours_enabled": provider.quiet_hours_enabled, "quiet_hours_start": provider.quiet_hours_start, diff --git a/backend/app/api/routes/print_queue.py b/backend/app/api/routes/print_queue.py index f74e21749..c3a625f5d 100644 --- a/backend/app/api/routes/print_queue.py +++ b/backend/app/api/routes/print_queue.py @@ -2,13 +2,17 @@ import json import logging +import xml.etree.ElementTree as ET +import zipfile from datetime import datetime +from pathlib import Path from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy import func, select from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import selectinload +from backend.app.core.config import settings from backend.app.core.database import get_db from backend.app.models.archive import PrintArchive from backend.app.models.library import LibraryFile @@ -22,12 +26,74 @@ from backend.app.schemas.print_queue import ( PrintQueueItemUpdate, PrintQueueReorder, ) +from backend.app.services.notification_service import notification_service logger = logging.getLogger(__name__) router = APIRouter(prefix="/queue", tags=["queue"]) +def _extract_filament_types_from_3mf(file_path: Path, plate_id: int | None = None) -> list[str]: + """Extract unique filament types from a 3MF file. + + Args: + file_path: Path to the 3MF file + plate_id: Optional plate index to filter for (for multi-plate files) + + Returns: + List of unique filament types (e.g., ["PLA", "PETG"]) + """ + types: set[str] = set() + + try: + with zipfile.ZipFile(file_path, "r") as zf: + if "Metadata/slice_info.config" not in zf.namelist(): + return [] + + content = zf.read("Metadata/slice_info.config").decode() + root = ET.fromstring(content) + + if plate_id is not None: + # Find the plate element with matching index + for plate_elem in root.findall(".//plate"): + plate_index = None + for meta in plate_elem.findall("metadata"): + if meta.get("key") == "index": + try: + plate_index = int(meta.get("value", "0")) + except ValueError: + pass + break + + if plate_index == plate_id: + for filament_elem in plate_elem.findall("filament"): + filament_type = filament_elem.get("type", "") + used_g = filament_elem.get("used_g", "0") + try: + used_grams = float(used_g) + except (ValueError, TypeError): + used_grams = 0 + if used_grams > 0 and filament_type: + types.add(filament_type) + break + else: + # No plate_id specified - extract all filaments with used_g > 0 + for filament_elem in root.findall(".//filament"): + filament_type = filament_elem.get("type", "") + used_g = filament_elem.get("used_g", "0") + try: + used_grams = float(used_g) + except (ValueError, TypeError): + used_grams = 0 + if used_grams > 0 and filament_type: + types.add(filament_type) + + except Exception as e: + logger.warning(f"Failed to extract filament types from {file_path}: {e}") + + return sorted(types) + + def _enrich_response(item: PrintQueueItem) -> PrintQueueItemResponse: """Add nested archive/printer/library_file info to response.""" # Parse ams_mapping from JSON string BEFORE model_validate @@ -38,11 +104,21 @@ def _enrich_response(item: PrintQueueItem) -> PrintQueueItemResponse: except json.JSONDecodeError: ams_mapping_parsed = None + # Parse required_filament_types from JSON string + required_filament_types_parsed = None + if item.required_filament_types: + try: + required_filament_types_parsed = json.loads(item.required_filament_types) + except json.JSONDecodeError: + required_filament_types_parsed = None + # Create response with parsed ams_mapping item_dict = { "id": item.id, "printer_id": item.printer_id, "target_model": item.target_model, + "required_filament_types": required_filament_types_parsed, + "waiting_reason": item.waiting_reason, "archive_id": item.archive_id, "library_file_id": item.library_file_id, "position": item.position, @@ -143,18 +219,39 @@ async def add_to_queue( if not result.scalars().first(): raise HTTPException(400, f"No active printers for model: {data.target_model}") - # Validate archive exists (if provided) + # Validate archive exists (if provided) and get it for filament extraction + archive = None if data.archive_id: result = await db.execute(select(PrintArchive).where(PrintArchive.id == data.archive_id)) - if not result.scalar_one_or_none(): + archive = result.scalar_one_or_none() + if not archive: raise HTTPException(400, "Archive not found") - # Validate library file exists (if provided) + # Validate library file exists (if provided) and get it for filament extraction + library_file = None if data.library_file_id: result = await db.execute(select(LibraryFile).where(LibraryFile.id == data.library_file_id)) - if not result.scalar_one_or_none(): + library_file = result.scalar_one_or_none() + if not library_file: raise HTTPException(400, "Library file not found") + # Extract filament types for model-based assignment (used by scheduler for validation) + required_filament_types = None + if data.target_model: + # Get file path from archive or library file + file_path = None + if archive: + file_path = settings.base_dir / archive.file_path + elif library_file: + lib_path = Path(library_file.file_path) + file_path = lib_path if lib_path.is_absolute() else settings.base_dir / library_file.file_path + + if file_path and file_path.exists(): + filament_types = _extract_filament_types_from_3mf(file_path, data.plate_id) + if filament_types: + required_filament_types = json.dumps(filament_types) + logger.info(f"Extracted filament types for model-based queue: {filament_types}") + # Get next position for this printer (or for unassigned/model-based items) if data.printer_id is not None: result = await db.execute( @@ -174,6 +271,7 @@ async def add_to_queue( item = PrintQueueItem( printer_id=data.printer_id, target_model=data.target_model, + required_filament_types=required_filament_types, archive_id=data.archive_id, library_file_id=data.library_file_id, scheduled_time=data.scheduled_time, @@ -215,6 +313,29 @@ async def add_to_queue( except Exception: pass # Don't fail queue add if MQTT fails + # Send notification for job added + try: + job_name = ( + item.archive.filename + if item.archive + else item.library_file.filename + if item.library_file + else f"Job #{item.id}" + ) + job_name = job_name.replace(".gcode.3mf", "").replace(".3mf", "") + target = ( + item.printer.name if item.printer else (f"Any {item.target_model}" if data.target_model else "Unassigned") + ) + await notification_service.on_queue_job_added( + job_name=job_name, + target=target, + db=db, + printer_id=item.printer_id, + printer_name=item.printer.name if item.printer else None, + ) + except Exception: + pass # Don't fail queue add if notification fails + return _enrich_response(item) diff --git a/backend/app/api/routes/settings.py b/backend/app/api/routes/settings.py index 50b416f0c..7ea8e7061 100644 --- a/backend/app/api/routes/settings.py +++ b/backend/app/api/routes/settings.py @@ -310,6 +310,13 @@ async def export_backup( "on_ams_ht_humidity_high": getattr(p, "on_ams_ht_humidity_high", False), "on_ams_ht_temperature_high": getattr(p, "on_ams_ht_temperature_high", False), "on_plate_not_empty": getattr(p, "on_plate_not_empty", True), + "on_queue_job_added": getattr(p, "on_queue_job_added", False), + "on_queue_job_assigned": getattr(p, "on_queue_job_assigned", False), + "on_queue_job_started": getattr(p, "on_queue_job_started", False), + "on_queue_job_waiting": getattr(p, "on_queue_job_waiting", True), + "on_queue_job_skipped": getattr(p, "on_queue_job_skipped", True), + "on_queue_job_failed": getattr(p, "on_queue_job_failed", True), + "on_queue_completed": getattr(p, "on_queue_completed", False), "quiet_hours_enabled": p.quiet_hours_enabled, "quiet_hours_start": p.quiet_hours_start, "quiet_hours_end": p.quiet_hours_end, @@ -1175,6 +1182,13 @@ async def import_backup( existing.on_ams_ht_humidity_high = provider_data.get("on_ams_ht_humidity_high", False) existing.on_ams_ht_temperature_high = provider_data.get("on_ams_ht_temperature_high", False) existing.on_plate_not_empty = provider_data.get("on_plate_not_empty", True) + existing.on_queue_job_added = provider_data.get("on_queue_job_added", False) + existing.on_queue_job_assigned = provider_data.get("on_queue_job_assigned", False) + existing.on_queue_job_started = provider_data.get("on_queue_job_started", False) + existing.on_queue_job_waiting = provider_data.get("on_queue_job_waiting", True) + existing.on_queue_job_skipped = provider_data.get("on_queue_job_skipped", True) + existing.on_queue_job_failed = provider_data.get("on_queue_job_failed", True) + existing.on_queue_completed = provider_data.get("on_queue_completed", False) existing.quiet_hours_enabled = provider_data.get("quiet_hours_enabled", False) existing.quiet_hours_start = provider_data.get("quiet_hours_start") existing.quiet_hours_end = provider_data.get("quiet_hours_end") @@ -1205,6 +1219,13 @@ async def import_backup( on_ams_ht_humidity_high=provider_data.get("on_ams_ht_humidity_high", False), on_ams_ht_temperature_high=provider_data.get("on_ams_ht_temperature_high", False), on_plate_not_empty=provider_data.get("on_plate_not_empty", True), + on_queue_job_added=provider_data.get("on_queue_job_added", False), + on_queue_job_assigned=provider_data.get("on_queue_job_assigned", False), + on_queue_job_started=provider_data.get("on_queue_job_started", False), + on_queue_job_waiting=provider_data.get("on_queue_job_waiting", True), + on_queue_job_skipped=provider_data.get("on_queue_job_skipped", True), + on_queue_job_failed=provider_data.get("on_queue_job_failed", True), + on_queue_completed=provider_data.get("on_queue_completed", False), quiet_hours_enabled=provider_data.get("quiet_hours_enabled", False), quiet_hours_start=provider_data.get("quiet_hours_start"), quiet_hours_end=provider_data.get("quiet_hours_end"), diff --git a/backend/app/core/database.py b/backend/app/core/database.py index ca4fb74b8..5b3175ff4 100644 --- a/backend/app/core/database.py +++ b/backend/app/core/database.py @@ -772,6 +772,34 @@ async def run_migrations(conn): except Exception: pass + # Migration: Add required_filament_types column to print_queue for filament validation + try: + await conn.execute(text("ALTER TABLE print_queue ADD COLUMN required_filament_types TEXT")) + except Exception: + pass + + # Migration: Add waiting_reason column to print_queue for status feedback + try: + await conn.execute(text("ALTER TABLE print_queue ADD COLUMN waiting_reason TEXT")) + except Exception: + pass + + # Migration: Add queue notification event columns to notification_providers + queue_notification_columns = [ + ("on_queue_job_added", "BOOLEAN DEFAULT 0"), + ("on_queue_job_assigned", "BOOLEAN DEFAULT 0"), + ("on_queue_job_started", "BOOLEAN DEFAULT 0"), + ("on_queue_job_waiting", "BOOLEAN DEFAULT 1"), + ("on_queue_job_skipped", "BOOLEAN DEFAULT 1"), + ("on_queue_job_failed", "BOOLEAN DEFAULT 1"), + ("on_queue_completed", "BOOLEAN DEFAULT 0"), + ] + for col_name, col_def in queue_notification_columns: + try: + await conn.execute(text(f"ALTER TABLE notification_providers ADD COLUMN {col_name} {col_def}")) + except Exception: + pass + async def seed_notification_templates(): """Seed default notification templates if they don't exist.""" diff --git a/backend/app/main.py b/backend/app/main.py index 40e49a34b..3f124524d 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -1988,6 +1988,34 @@ async def on_print_complete(printer_id: int, data: dict): except Exception: pass # Don't fail if MQTT fails + # Check if queue is now empty and send notification + try: + from sqlalchemy import func + + # Count remaining pending items + count_result = await db.execute( + select(func.count(PrintQueueItem.id)).where(PrintQueueItem.status == "pending") + ) + pending_count = count_result.scalar() or 0 + + if pending_count == 0: + # Count how many completed today (rough approximation) + today_start = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + completed_result = await db.execute( + select(func.count(PrintQueueItem.id)).where( + PrintQueueItem.status.in_(["completed", "failed", "skipped"]), + PrintQueueItem.completed_at >= today_start, + ) + ) + completed_count = completed_result.scalar() or 1 + + await notification_service.on_queue_completed( + completed_count=completed_count, + db=db, + ) + except Exception: + pass # Don't fail if notification fails + # Handle auto_off_after - power off printer if requested (after cooldown) if queue_item.auto_off_after: result = await db.execute(select(SmartPlug).where(SmartPlug.printer_id == printer_id)) diff --git a/backend/app/models/notification.py b/backend/app/models/notification.py index 4f49ed64b..c04b140d7 100644 --- a/backend/app/models/notification.py +++ b/backend/app/models/notification.py @@ -83,6 +83,15 @@ class NotificationProvider(Base): # Event triggers - Build plate detection on_plate_not_empty = Column(Boolean, default=True) # Objects detected on plate before print + # Event triggers - Print queue + on_queue_job_added = Column(Boolean, default=False) # Job added to queue + on_queue_job_assigned = Column(Boolean, default=False) # Model-based job assigned to printer + on_queue_job_started = Column(Boolean, default=False) # Queue job started printing + on_queue_job_waiting = Column(Boolean, default=True) # Job waiting for filament + on_queue_job_skipped = Column(Boolean, default=True) # Job skipped (previous print failed) + on_queue_job_failed = Column(Boolean, default=True) # Job failed to start + on_queue_completed = Column(Boolean, default=False) # All pending jobs finished + # Quiet hours (do not disturb) quiet_hours_enabled = Column(Boolean, default=False) quiet_hours_start = Column(String(5), nullable=True) # HH:MM format, e.g., "22:00" diff --git a/backend/app/models/notification_template.py b/backend/app/models/notification_template.py index 9dcb9ccbc..fb21b9456 100644 --- a/backend/app/models/notification_template.py +++ b/backend/app/models/notification_template.py @@ -103,4 +103,47 @@ DEFAULT_TEMPLATES = [ "title_template": "Bambuddy Test", "body_template": "This is a test notification. If you see this, notifications are working!", }, + # Queue notifications + { + "event_type": "queue_job_added", + "name": "Queue Job Added", + "title_template": "Job Queued", + "body_template": "{job_name} added to queue for {target}", + }, + { + "event_type": "queue_job_assigned", + "name": "Queue Job Assigned", + "title_template": "Job Assigned", + "body_template": "{job_name} assigned to {printer} (from Any {target_model} queue)", + }, + { + "event_type": "queue_job_started", + "name": "Queue Job Started", + "title_template": "Queue Job Started", + "body_template": "{printer}: {job_name}\nEstimated: {estimated_time}", + }, + { + "event_type": "queue_job_waiting", + "name": "Queue Job Waiting", + "title_template": "Job Waiting for Filament", + "body_template": "{job_name} waiting for {target_model}\n{waiting_reason}", + }, + { + "event_type": "queue_job_skipped", + "name": "Queue Job Skipped", + "title_template": "Job Skipped", + "body_template": "{printer}: {job_name}\nReason: {reason}", + }, + { + "event_type": "queue_job_failed", + "name": "Queue Job Failed", + "title_template": "Job Failed to Start", + "body_template": "{printer}: {job_name}\nReason: {reason}", + }, + { + "event_type": "queue_completed", + "name": "Queue Completed", + "title_template": "Queue Complete", + "body_template": "All {completed_count} queued jobs have finished", + }, ] diff --git a/backend/app/models/print_queue.py b/backend/app/models/print_queue.py index cd33ee121..53c54cb93 100644 --- a/backend/app/models/print_queue.py +++ b/backend/app/models/print_queue.py @@ -18,6 +18,12 @@ class PrintQueueItem(Base): # Target printer model for model-based assignment (mutually exclusive with printer_id) # When set, scheduler assigns to any idle printer of matching model target_model: Mapped[str | None] = mapped_column(String(50), nullable=True) + # Required filament types for model-based assignment (JSON array, e.g., '["PLA", "PETG"]') + # Used by scheduler to validate printer has compatible filaments loaded + required_filament_types: Mapped[str | None] = mapped_column(Text, nullable=True) + # Waiting reason - explains why a model-based job hasn't started yet + # Set by scheduler when no matching printer is available + waiting_reason: Mapped[str | None] = mapped_column(Text, nullable=True) # Either archive_id OR library_file_id must be set (archive created at print start from library file) archive_id: Mapped[int | None] = mapped_column(ForeignKey("print_archives.id", ondelete="CASCADE"), nullable=True) library_file_id: Mapped[int | None] = mapped_column( diff --git a/backend/app/schemas/notification.py b/backend/app/schemas/notification.py index e0285f464..ca8ff5b41 100644 --- a/backend/app/schemas/notification.py +++ b/backend/app/schemas/notification.py @@ -53,6 +53,15 @@ class NotificationProviderBase(BaseModel): # Event triggers - Build plate detection on_plate_not_empty: bool = Field(default=True, description="Notify when objects detected on plate before print") + # Event triggers - Print queue + on_queue_job_added: bool = Field(default=False, description="Notify when job is added to queue") + on_queue_job_assigned: bool = Field(default=False, description="Notify when model-based job is assigned to printer") + on_queue_job_started: bool = Field(default=False, description="Notify when queue job starts printing") + on_queue_job_waiting: bool = Field(default=True, description="Notify when job is waiting for filament") + on_queue_job_skipped: bool = Field(default=True, description="Notify when job is skipped") + on_queue_job_failed: bool = Field(default=True, description="Notify when job fails to start") + on_queue_completed: bool = Field(default=False, description="Notify when all queue jobs finish") + # Quiet hours quiet_hours_enabled: bool = Field(default=False, description="Enable quiet hours") quiet_hours_start: str | None = Field(default=None, description="Start time in HH:MM format") @@ -120,6 +129,15 @@ class NotificationProviderUpdate(BaseModel): # Event triggers - Build plate detection on_plate_not_empty: bool | None = None + # Event triggers - Print queue + on_queue_job_added: bool | None = None + on_queue_job_assigned: bool | None = None + on_queue_job_started: bool | None = None + on_queue_job_waiting: bool | None = None + on_queue_job_skipped: bool | None = None + on_queue_job_failed: bool | None = None + on_queue_completed: bool | None = None + # Quiet hours quiet_hours_enabled: bool | None = None quiet_hours_start: str | None = None diff --git a/backend/app/schemas/print_queue.py b/backend/app/schemas/print_queue.py index f64a0be4a..785145126 100644 --- a/backend/app/schemas/print_queue.py +++ b/backend/app/schemas/print_queue.py @@ -18,6 +18,7 @@ UTCDatetime = Annotated[datetime | None, PlainSerializer(serialize_utc_datetime) class PrintQueueItemCreate(BaseModel): printer_id: int | None = None # None = unassigned, user assigns later target_model: str | None = None # Target printer model (mutually exclusive with printer_id) + required_filament_types: list[str] | None = None # Required filament types for model-based assignment # Either archive_id OR library_file_id must be provided archive_id: int | None = None library_file_id: int | None = None @@ -62,6 +63,8 @@ class PrintQueueItemResponse(BaseModel): id: int printer_id: int | None # None = unassigned target_model: str | None = None # Target printer model for model-based assignment + required_filament_types: list[str] | None = None # Required filament types for model-based assignment + waiting_reason: str | None = None # Why a model-based job hasn't started yet archive_id: int | None # None if library_file_id is set (archive created at print start) library_file_id: int | None # For queue items from library files position: int diff --git a/backend/app/services/notification_service.py b/backend/app/services/notification_service.py index 2c666ff02..92a51cd14 100644 --- a/backend/app/services/notification_service.py +++ b/backend/app/services/notification_service.py @@ -945,6 +945,156 @@ class NotificationService: """Clear the template cache. Call this when templates are updated.""" self._template_cache.clear() + # ==================== Queue Notifications ==================== + + async def on_queue_job_added( + self, + job_name: str, + target: str, + db: AsyncSession, + printer_id: int | None = None, + printer_name: str | None = None, + ): + """Handle queue job added event.""" + providers = await self._get_providers_for_event(db, "on_queue_job_added", printer_id) + if not providers: + return + + variables = { + "job_name": job_name, + "target": target, # e.g., "Printer1" or "Any X1C" + "printer": printer_name or target, + } + + title, message = await self._build_message_from_template(db, "queue_job_added", variables) + await self._send_to_providers(providers, title, message, db, "queue_job_added", printer_id, printer_name) + + async def on_queue_job_assigned( + self, + job_name: str, + printer_id: int, + printer_name: str, + target_model: str, + db: AsyncSession, + ): + """Handle model-based job assigned to printer event.""" + providers = await self._get_providers_for_event(db, "on_queue_job_assigned", printer_id) + if not providers: + return + + variables = { + "job_name": job_name, + "printer": printer_name, + "target_model": target_model, + } + + title, message = await self._build_message_from_template(db, "queue_job_assigned", variables) + await self._send_to_providers(providers, title, message, db, "queue_job_assigned", printer_id, printer_name) + + async def on_queue_job_started( + self, + job_name: str, + printer_id: int, + printer_name: str, + db: AsyncSession, + estimated_time: int | None = None, + ): + """Handle queue job started printing event.""" + providers = await self._get_providers_for_event(db, "on_queue_job_started", printer_id) + if not providers: + return + + variables = { + "job_name": job_name, + "printer": printer_name, + "estimated_time": self._format_duration(estimated_time), + } + + title, message = await self._build_message_from_template(db, "queue_job_started", variables) + await self._send_to_providers(providers, title, message, db, "queue_job_started", printer_id, printer_name) + + async def on_queue_job_waiting( + self, + job_name: str, + target_model: str, + waiting_reason: str, + db: AsyncSession, + ): + """Handle job waiting for filament event.""" + providers = await self._get_providers_for_event(db, "on_queue_job_waiting", None) + if not providers: + return + + variables = { + "job_name": job_name, + "target_model": target_model, + "waiting_reason": waiting_reason, + } + + title, message = await self._build_message_from_template(db, "queue_job_waiting", variables) + await self._send_to_providers(providers, title, message, db, "queue_job_waiting") + + async def on_queue_job_skipped( + self, + job_name: str, + printer_id: int, + printer_name: str, + reason: str, + db: AsyncSession, + ): + """Handle job skipped event (e.g., previous print failed).""" + providers = await self._get_providers_for_event(db, "on_queue_job_skipped", printer_id) + if not providers: + return + + variables = { + "job_name": job_name, + "printer": printer_name, + "reason": reason, + } + + title, message = await self._build_message_from_template(db, "queue_job_skipped", variables) + await self._send_to_providers(providers, title, message, db, "queue_job_skipped", printer_id, printer_name) + + async def on_queue_job_failed( + self, + job_name: str, + printer_id: int | None, + printer_name: str | None, + reason: str, + db: AsyncSession, + ): + """Handle job failed to start event (upload error, etc.).""" + providers = await self._get_providers_for_event(db, "on_queue_job_failed", printer_id) + if not providers: + return + + variables = { + "job_name": job_name, + "printer": printer_name or "Unknown", + "reason": reason, + } + + title, message = await self._build_message_from_template(db, "queue_job_failed", variables) + await self._send_to_providers(providers, title, message, db, "queue_job_failed", printer_id, printer_name) + + async def on_queue_completed( + self, + completed_count: int, + db: AsyncSession, + ): + """Handle all queue jobs completed event.""" + providers = await self._get_providers_for_event(db, "on_queue_completed", None) + if not providers: + return + + variables = { + "completed_count": str(completed_count), + } + + title, message = await self._build_message_from_template(db, "queue_completed", variables) + await self._send_to_providers(providers, title, message, db, "queue_completed") + async def _queue_for_digest( self, provider: NotificationProvider, diff --git a/backend/app/services/print_scheduler.py b/backend/app/services/print_scheduler.py index 1c9728bca..c6759809f 100644 --- a/backend/app/services/print_scheduler.py +++ b/backend/app/services/print_scheduler.py @@ -15,6 +15,7 @@ from backend.app.models.print_queue import PrintQueueItem from backend.app.models.printer import Printer from backend.app.models.smart_plug import SmartPlug from backend.app.services.bambu_ftp import delete_file_async, get_ftp_retry_settings, upload_file_async, with_ftp_retry +from backend.app.services.notification_service import notification_service from backend.app.services.printer_manager import printer_manager from backend.app.services.tasmota import tasmota_service @@ -114,6 +115,17 @@ class PrintScheduler: item.completed_at = datetime.now() await db.commit() logger.info(f"Skipped queue item {item.id} - previous print failed") + + # Send notification + job_name = await self._get_job_name(db, item) + printer = await self._get_printer(db, item.printer_id) + await notification_service.on_queue_job_skipped( + job_name=job_name, + printer_id=item.printer_id, + printer_name=printer.name if printer else "Unknown", + reason="Previous print failed or was aborted", + db=db, + ) continue # Start the print @@ -122,7 +134,36 @@ class PrintScheduler: elif item.target_model: # Model-based assignment - find any idle printer of matching model - printer_id = await self._find_idle_printer_for_model(db, item.target_model, busy_printers) + # Parse required filament types if present + required_types = None + if item.required_filament_types: + try: + import json + + required_types = json.loads(item.required_filament_types) + except json.JSONDecodeError: + pass + + printer_id, waiting_reason = await self._find_idle_printer_for_model( + db, item.target_model, busy_printers, required_types + ) + + # Update waiting_reason if changed and send notification when first waiting + if item.waiting_reason != waiting_reason: + was_waiting = item.waiting_reason is not None + item.waiting_reason = waiting_reason + await db.commit() + + # Send waiting notification only when transitioning to waiting state + if waiting_reason and not was_waiting: + job_name = await self._get_job_name(db, item) + await notification_service.on_queue_job_waiting( + job_name=job_name, + target_model=item.target_model, + waiting_reason=waiting_reason, + db=db, + ) + if printer_id: # Check condition (previous print success) before assigning if item.require_previous_success: @@ -132,33 +173,150 @@ class PrintScheduler: item.completed_at = datetime.now() await db.commit() logger.info(f"Skipped queue item {item.id} - previous print failed") + + # Send notification + job_name = await self._get_job_name(db, item) + printer = await self._get_printer(db, printer_id) + await notification_service.on_queue_job_skipped( + job_name=job_name, + printer_id=printer_id, + printer_name=printer.name if printer else "Unknown", + reason="Previous print failed or was aborted", + db=db, + ) continue - # Assign printer and start + # Assign printer and start - clear waiting reason item.printer_id = printer_id + item.waiting_reason = None logger.info(f"Model-based assignment: queue item {item.id} assigned to printer {printer_id}") + + # Send assignment notification + job_name = await self._get_job_name(db, item) + printer = await self._get_printer(db, printer_id) + await notification_service.on_queue_job_assigned( + job_name=job_name, + printer_id=printer_id, + printer_name=printer.name if printer else "Unknown", + target_model=item.target_model, + db=db, + ) + await self._start_print(db, item) busy_printers.add(printer_id) - async def _find_idle_printer_for_model(self, db: AsyncSession, model: str, exclude_ids: set[int]) -> int | None: - """Find an idle, connected printer matching the model. + async def _find_idle_printer_for_model( + self, + db: AsyncSession, + model: str, + exclude_ids: set[int], + required_filament_types: list[str] | None = None, + ) -> tuple[int | None, str | None]: + """Find an idle, connected printer matching the model with compatible filaments. Args: db: Database session model: Printer model to match (e.g., "X1C", "P1S") exclude_ids: Printer IDs to exclude (already busy) + required_filament_types: Optional list of filament types needed (e.g., ["PLA", "PETG"]) + If provided, only printers with all required types loaded will match. Returns: - Printer ID if found, None otherwise + Tuple of (printer_id, waiting_reason): + - (printer_id, None) if a matching printer was found + - (None, reason) if no printer is available, with explanation """ result = await db.execute( select(Printer).where(Printer.model == model).where(Printer.is_active == True) # noqa: E712 ) - for printer in result.scalars().all(): - if printer.id not in exclude_ids: - if self._is_printer_idle(printer.id) and printer_manager.is_connected(printer.id): - return printer.id - return None + printers = list(result.scalars().all()) + + if not printers: + return None, f"No active {model} printers configured" + + # Track reasons for skipping printers + printers_busy = [] + printers_offline = [] + printers_missing_filament = [] + + for printer in printers: + if printer.id in exclude_ids: + printers_busy.append(printer.name) + continue + + is_connected = printer_manager.is_connected(printer.id) + is_idle = self._is_printer_idle(printer.id) if is_connected else False + + if not is_connected: + printers_offline.append(printer.name) + continue + + if not is_idle: + printers_busy.append(printer.name) + continue + + # Validate filament compatibility if required types are specified + if required_filament_types: + missing = self._get_missing_filament_types(printer.id, required_filament_types) + if missing: + printers_missing_filament.append((printer.name, missing)) + logger.debug(f"Skipping printer {printer.id} ({printer.name}) - missing filaments: {missing}") + continue + + # Found a matching printer - clear waiting reason + return printer.id, None + + # Build waiting reason from what we found + reasons = [] + if printers_missing_filament: + # Filament mismatch is most actionable - show first + names_and_missing = [f"{name} (needs {', '.join(missing)})" for name, missing in printers_missing_filament] + reasons.append(f"Waiting for filament: {'; '.join(names_and_missing)}") + if printers_busy: + reasons.append(f"Busy: {', '.join(printers_busy)}") + if printers_offline: + reasons.append(f"Offline: {', '.join(printers_offline)}") + + return None, " | ".join(reasons) if reasons else f"No available {model} printers" + + def _get_missing_filament_types(self, printer_id: int, required_types: list[str]) -> list[str]: + """Get the list of required filament types that are not loaded on the printer. + + Args: + printer_id: The printer ID + required_types: List of filament types needed (e.g., ["PLA", "PETG"]) + + Returns: + List of missing filament types (empty if all are loaded) + """ + status = printer_manager.get_status(printer_id) + if not status: + return required_types # Can't determine, assume all missing + + # Collect all filament types loaded on this printer (AMS units + external spool) + loaded_types: set[str] = set() + + # Check AMS units + if status.ams_units: + for ams_unit in status.ams_units: + for tray in ams_unit.get("tray", []): + tray_type = tray.get("tray_type") + if tray_type: + loaded_types.add(tray_type.upper()) + + # Check external spool (virtual tray) + if status.virtual_tray: + vt_type = status.virtual_tray.get("tray_type") + if vt_type: + loaded_types.add(vt_type.upper()) + + # Find which required types are missing (case-insensitive comparison) + missing = [] + for req_type in required_types: + if req_type.upper() not in loaded_types: + missing.append(req_type) + + return missing def _is_printer_idle(self, printer_id: int) -> bool: """Check if a printer is connected and idle.""" @@ -262,6 +420,25 @@ class PrintScheduler: logger.info(f"Auto-off: Powering off printer {item.printer_id}") await tasmota_service.turn_off(plug) + async def _get_job_name(self, db: AsyncSession, item: PrintQueueItem) -> str: + """Get a human-readable name for a queue item.""" + if item.archive_id: + result = await db.execute(select(PrintArchive).where(PrintArchive.id == item.archive_id)) + archive = result.scalar_one_or_none() + if archive: + return archive.filename.replace(".gcode.3mf", "").replace(".3mf", "") + if item.library_file_id: + result = await db.execute(select(LibraryFile).where(LibraryFile.id == item.library_file_id)) + library_file = result.scalar_one_or_none() + if library_file: + return library_file.filename.replace(".gcode.3mf", "").replace(".3mf", "") + return f"Job #{item.id}" + + async def _get_printer(self, db: AsyncSession, printer_id: int) -> Printer | None: + """Get printer by ID.""" + result = await db.execute(select(Printer).where(Printer.id == printer_id)) + return result.scalar_one_or_none() + async def _start_print(self, db: AsyncSession, item: PrintQueueItem): """Upload file and start print for a queue item. @@ -413,6 +590,16 @@ class PrintScheduler: item.completed_at = datetime.utcnow() await db.commit() logger.error(f"Queue item {item.id}: FTP upload failed") + + # Send failure notification + await notification_service.on_queue_job_failed( + job_name=filename.replace(".gcode.3mf", "").replace(".3mf", ""), + printer_id=printer.id, + printer_name=printer.name, + reason="Failed to upload file to printer", + db=db, + ) + await self._power_off_if_needed(db, item) return @@ -453,6 +640,22 @@ class PrintScheduler: await db.commit() logger.info(f"Queue item {item.id}: Print started - {filename}") + # Get estimated time for notification + estimated_time = None + if archive and archive.print_time_seconds: + estimated_time = archive.print_time_seconds + elif library_file and library_file.print_time_seconds: + estimated_time = library_file.print_time_seconds + + # Send job started notification + await notification_service.on_queue_job_started( + job_name=filename.replace(".gcode.3mf", "").replace(".3mf", ""), + printer_id=printer.id, + printer_name=printer.name, + db=db, + estimated_time=estimated_time, + ) + # MQTT relay - publish queue job started try: from backend.app.services.mqtt_relay import mqtt_relay @@ -472,6 +675,16 @@ class PrintScheduler: item.completed_at = datetime.utcnow() await db.commit() logger.error(f"Queue item {item.id}: Failed to start print") + + # Send failure notification + await notification_service.on_queue_job_failed( + job_name=filename.replace(".gcode.3mf", "").replace(".3mf", ""), + printer_id=printer.id, + printer_name=printer.name, + reason="Failed to send print command", + db=db, + ) + await self._power_off_if_needed(db, item) diff --git a/frontend/src/__tests__/components/NotificationProviderCard.test.tsx b/frontend/src/__tests__/components/NotificationProviderCard.test.tsx index ffed64ee1..00d768c05 100644 --- a/frontend/src/__tests__/components/NotificationProviderCard.test.tsx +++ b/frontend/src/__tests__/components/NotificationProviderCard.test.tsx @@ -63,6 +63,14 @@ const createMockProvider = ( on_ams_temperature_high: false, on_ams_ht_humidity_high: false, on_ams_ht_temperature_high: false, + on_plate_not_empty: true, + on_queue_job_added: false, + on_queue_job_assigned: false, + on_queue_job_started: false, + on_queue_job_waiting: true, + on_queue_job_skipped: true, + on_queue_job_failed: true, + on_queue_completed: false, quiet_hours_enabled: false, quiet_hours_start: null, quiet_hours_end: null, @@ -282,3 +290,83 @@ describe('NotificationProviderCard AMS toggles', () => { }); }); }); + +describe('NotificationProviderCard Queue notifications', () => { + describe('queue job notifications', () => { + it('includes on_queue_job_added in provider data', () => { + const provider = createMockProvider({ on_queue_job_added: true }); + expect(provider.on_queue_job_added).toBe(true); + }); + + it('includes on_queue_job_assigned in provider data', () => { + const provider = createMockProvider({ on_queue_job_assigned: true }); + expect(provider.on_queue_job_assigned).toBe(true); + }); + + it('includes on_queue_job_started in provider data', () => { + const provider = createMockProvider({ on_queue_job_started: true }); + expect(provider.on_queue_job_started).toBe(true); + }); + + it('includes on_queue_job_waiting in provider data', () => { + const provider = createMockProvider({ on_queue_job_waiting: true }); + expect(provider.on_queue_job_waiting).toBe(true); + }); + + it('includes on_queue_job_skipped in provider data', () => { + const provider = createMockProvider({ on_queue_job_skipped: true }); + expect(provider.on_queue_job_skipped).toBe(true); + }); + + it('includes on_queue_job_failed in provider data', () => { + const provider = createMockProvider({ on_queue_job_failed: true }); + expect(provider.on_queue_job_failed).toBe(true); + }); + + it('includes on_queue_completed in provider data', () => { + const provider = createMockProvider({ on_queue_completed: true }); + expect(provider.on_queue_completed).toBe(true); + }); + }); + + describe('queue notification defaults', () => { + it('defaults actionable notifications to true', () => { + const provider = createMockProvider(); + // These should default to true (actionable - user needs to do something) + expect(provider.on_queue_job_waiting).toBe(true); + expect(provider.on_queue_job_skipped).toBe(true); + expect(provider.on_queue_job_failed).toBe(true); + }); + + it('defaults informational notifications to false', () => { + const provider = createMockProvider(); + // These should default to false (informational only) + expect(provider.on_queue_job_added).toBe(false); + expect(provider.on_queue_job_assigned).toBe(false); + expect(provider.on_queue_job_started).toBe(false); + expect(provider.on_queue_completed).toBe(false); + }); + }); + + describe('queue notification combinations', () => { + it('supports all queue toggles independently', () => { + const provider = createMockProvider({ + on_queue_job_added: true, + on_queue_job_assigned: false, + on_queue_job_started: true, + on_queue_job_waiting: false, + on_queue_job_skipped: true, + on_queue_job_failed: false, + on_queue_completed: true, + }); + + expect(provider.on_queue_job_added).toBe(true); + expect(provider.on_queue_job_assigned).toBe(false); + expect(provider.on_queue_job_started).toBe(true); + expect(provider.on_queue_job_waiting).toBe(false); + expect(provider.on_queue_job_skipped).toBe(true); + expect(provider.on_queue_job_failed).toBe(false); + expect(provider.on_queue_completed).toBe(true); + }); + }); +}); diff --git a/frontend/src/__tests__/components/UploadModal.test.tsx b/frontend/src/__tests__/components/UploadModal.test.tsx index 424961348..70cd09e1e 100644 --- a/frontend/src/__tests__/components/UploadModal.test.tsx +++ b/frontend/src/__tests__/components/UploadModal.test.tsx @@ -10,20 +10,12 @@ import { UploadModal } from '../../components/UploadModal'; import { http, HttpResponse } from 'msw'; import { server } from '../mocks/server'; -const mockPrinters = [ - { id: 1, name: 'X1 Carbon', model: 'X1C', serial_number: '123' }, - { id: 2, name: 'P1S', model: 'P1S', serial_number: '456' }, -]; - describe('UploadModal', () => { const mockOnClose = vi.fn(); beforeEach(() => { vi.clearAllMocks(); server.use( - http.get('/api/v1/printers/', () => { - return HttpResponse.json(mockPrinters); - }), http.post('/api/v1/archives/upload-bulk', async () => { return HttpResponse.json({ uploaded: 1, @@ -54,17 +46,6 @@ describe('UploadModal', () => { expect(screen.getByRole('button', { name: 'Browse Files' })).toBeInTheDocument(); }); - it('renders printer selection dropdown', async () => { - render(); - - await waitFor(() => { - expect(screen.getByText('Associate with printer (optional)')).toBeInTheDocument(); - }); - - const select = screen.getByRole('combobox'); - expect(select).toBeInTheDocument(); - }); - it('renders Cancel button', () => { render(); @@ -79,32 +60,6 @@ describe('UploadModal', () => { }); }); - describe('printer selection', () => { - it('shows available printers in dropdown', async () => { - render(); - - await waitFor(() => { - // Check for printer options in the select - expect(screen.getByRole('option', { name: 'No printer' })).toBeInTheDocument(); - expect(screen.getByRole('option', { name: 'X1 Carbon' })).toBeInTheDocument(); - expect(screen.getByRole('option', { name: 'P1S' })).toBeInTheDocument(); - }); - }); - - it('allows selecting a printer', async () => { - render(); - - await waitFor(() => { - expect(screen.getByRole('option', { name: 'X1 Carbon' })).toBeInTheDocument(); - }); - - const select = screen.getByRole('combobox'); - fireEvent.change(select, { target: { value: '1' } }); - - expect(select).toHaveValue('1'); - }); - }); - describe('file handling with initialFiles', () => { it('shows initial files when provided', () => { const initialFiles = [ diff --git a/frontend/src/api/client.ts b/frontend/src/api/client.ts index 00f4aef2a..5e08f3101 100644 --- a/frontend/src/api/client.ts +++ b/frontend/src/api/client.ts @@ -1002,6 +1002,8 @@ export interface PrintQueueItem { id: number; printer_id: number | null; // null = unassigned target_model: string | null; // Target printer model for model-based assignment + required_filament_types: string[] | null; // Required filament types for model-based assignment + waiting_reason: string | null; // Why a model-based job hasn't started yet // Either archive_id OR library_file_id must be set (archive created at print start) archive_id: number | null; library_file_id: number | null; @@ -1215,6 +1217,14 @@ export interface NotificationProvider { on_ams_ht_temperature_high: boolean; // Build plate detection on_plate_not_empty: boolean; + // Print queue events + on_queue_job_added: boolean; + on_queue_job_assigned: boolean; + on_queue_job_started: boolean; + on_queue_job_waiting: boolean; + on_queue_job_skipped: boolean; + on_queue_job_failed: boolean; + on_queue_completed: boolean; // Quiet hours quiet_hours_enabled: boolean; quiet_hours_start: string | null; @@ -1257,6 +1267,14 @@ export interface NotificationProviderCreate { on_ams_ht_temperature_high?: boolean; // Build plate detection on_plate_not_empty?: boolean; + // Print queue events + on_queue_job_added?: boolean; + on_queue_job_assigned?: boolean; + on_queue_job_started?: boolean; + on_queue_job_waiting?: boolean; + on_queue_job_skipped?: boolean; + on_queue_job_failed?: boolean; + on_queue_completed?: boolean; // Quiet hours quiet_hours_enabled?: boolean; quiet_hours_start?: string | null; @@ -1292,6 +1310,14 @@ export interface NotificationProviderUpdate { on_ams_ht_temperature_high?: boolean; // Build plate detection on_plate_not_empty?: boolean; + // Print queue events + on_queue_job_added?: boolean; + on_queue_job_assigned?: boolean; + on_queue_job_started?: boolean; + on_queue_job_waiting?: boolean; + on_queue_job_skipped?: boolean; + on_queue_job_failed?: boolean; + on_queue_completed?: boolean; // Quiet hours quiet_hours_enabled?: boolean; quiet_hours_start?: string | null; diff --git a/frontend/src/components/NotificationProviderCard.tsx b/frontend/src/components/NotificationProviderCard.tsx index 15159cb60..01a7e96b5 100644 --- a/frontend/src/components/NotificationProviderCard.tsx +++ b/frontend/src/components/NotificationProviderCard.tsx @@ -398,6 +398,88 @@ export function NotificationProviderCard({ provider, onEdit }: NotificationProvi + {/* Print Queue Events */} +
+

Print Queue

+ +
+
+

Job Added

+

Job added to queue

+
+ updateMutation.mutate({ on_queue_job_added: checked })} + /> +
+ +
+
+

Job Assigned

+

Model-based job assigned to printer

+
+ updateMutation.mutate({ on_queue_job_assigned: checked })} + /> +
+ +
+
+

Job Started

+

Queue job started printing

+
+ updateMutation.mutate({ on_queue_job_started: checked })} + /> +
+ +
+
+

Job Waiting

+

Job waiting for filament

+
+ updateMutation.mutate({ on_queue_job_waiting: checked })} + /> +
+ +
+
+

Job Skipped

+

Job skipped (previous failed)

+
+ updateMutation.mutate({ on_queue_job_skipped: checked })} + /> +
+ +
+
+

Job Failed

+

Job failed to start

+
+ updateMutation.mutate({ on_queue_job_failed: checked })} + /> +
+ +
+
+

Queue Complete

+

All queue jobs finished

+
+ updateMutation.mutate({ on_queue_completed: checked })} + /> +
+
+ {/* Quiet Hours */}
diff --git a/frontend/src/pages/QueuePage.tsx b/frontend/src/pages/QueuePage.tsx index fabe49212..1e2b21425 100644 --- a/frontend/src/pages/QueuePage.tsx +++ b/frontend/src/pages/QueuePage.tsx @@ -77,7 +77,17 @@ function formatRelativeTime(dateString: string | null, timeFormat: TimeFormat = return formatDateTime(dateString, timeFormat); } -function StatusBadge({ status }: { status: PrintQueueItem['status'] }) { +function StatusBadge({ status, waitingReason }: { status: PrintQueueItem['status']; waitingReason?: string | null }) { + // Special case: pending with waiting_reason shows as "Waiting" + if (status === 'pending' && waitingReason) { + return ( + + + Waiting + + ); + } + const config = { pending: { icon: Clock, color: 'text-status-warning bg-status-warning/10 border-status-warning/20', label: 'Pending' }, printing: { icon: Play, color: 'text-blue-400 bg-blue-400/10 border-blue-400/20', label: 'Printing' }, @@ -394,7 +404,7 @@ function SortableQueueItem({ {item.target_model - ? `Any ${item.target_model}` + ? `Any ${item.target_model}${item.required_filament_types?.length ? ` (${item.required_filament_types.join(', ')})` : ''}` : item.printer_id === null ? 'Unassigned' : (item.printer_name || `Printer #${item.printer_id}`)} @@ -444,6 +454,14 @@ function SortableQueueItem({
)} + {/* Waiting reason for model-based assignments */} + {item.waiting_reason && item.status === 'pending' && ( +

+ + {item.waiting_reason} +

+ )} + {/* Error message */} {item.error_message && (

@@ -454,7 +472,7 @@ function SortableQueueItem({

{/* Status badge */} - + {/* Actions */}
diff --git a/static/assets/index-8OJBC-HQ.css b/static/assets/index-8OJBC-HQ.css new file mode 100644 index 000000000..f29f89221 --- /dev/null +++ b/static/assets/index-8OJBC-HQ.css @@ -0,0 +1 @@ +@import"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap";@layer properties,theme,base,components,utilities;@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-orange-200:oklch(90.1% .076 70.697);--color-orange-300:oklch(83.7% .128 66.29);--color-orange-400:oklch(75% .183 55.934);--color-orange-500:oklch(70.5% .213 47.604);--color-orange-600:oklch(64.6% .222 41.116);--color-orange-700:oklch(55.3% .195 38.402);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-600:oklch(66.6% .179 58.318);--color-yellow-200:oklch(94.5% .129 101.54);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--color-yellow-600:oklch(68.1% .162 75.834);--color-yellow-700:oklch(55.4% .135 66.442);--color-green-100:oklch(96.2% .044 156.743);--color-green-300:oklch(87.1% .15 154.449);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-green-600:oklch(62.7% .194 149.214);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-cyan-300:oklch(86.5% .127 207.078);--color-cyan-400:oklch(78.9% .154 211.53);--color-cyan-500:oklch(71.5% .143 215.221);--color-cyan-600:oklch(60.9% .126 221.723);--color-blue-50:oklch(97% .014 254.604);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-300:oklch(80.9% .105 251.813);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-indigo-400:oklch(67.3% .182 276.935);--color-indigo-500:oklch(58.5% .233 277.117);--color-purple-300:oklch(82.7% .119 306.383);--color-purple-400:oklch(71.4% .203 305.504);--color-purple-500:oklch(62.7% .265 303.9);--color-rose-300:oklch(81% .117 11.638);--color-rose-400:oklch(71.2% .194 13.428);--color-rose-500:oklch(64.5% .246 16.439);--color-rose-600:oklch(58.6% .253 17.585);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-6xl:72rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--blur-sm:8px;--aspect-video:16/9;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-bambu-green:var(--accent);--color-bambu-green-light:var(--accent-light);--color-bambu-green-dark:var(--accent-dark);--color-status-ok:var(--status-ok);--color-status-error:var(--status-error);--color-status-warning:var(--status-warning);--color-bambu-dark:var(--bg-primary);--color-bambu-dark-secondary:var(--bg-secondary);--color-bambu-dark-tertiary:var(--bg-tertiary);--color-bambu-gray:var(--text-muted);--color-bambu-gray-light:var(--text-secondary);--color-bambu-gray-dark:var(--text-tertiary)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing)*0)}.inset-x-0{inset-inline:calc(var(--spacing)*0)}.inset-y-0{inset-block:calc(var(--spacing)*0)}.-top-1{top:calc(var(--spacing)*-1)}.-top-1\.5{top:calc(var(--spacing)*-1.5)}.top-0{top:calc(var(--spacing)*0)}.top-0\.5{top:calc(var(--spacing)*.5)}.top-1{top:calc(var(--spacing)*1)}.top-1\.5{top:calc(var(--spacing)*1.5)}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing)*2)}.top-4{top:calc(var(--spacing)*4)}.top-8{top:calc(var(--spacing)*8)}.top-\[2px\]{top:2px}.top-\[3px\]{top:3px}.top-full{top:100%}.-right-1{right:calc(var(--spacing)*-1)}.-right-1\.5{right:calc(var(--spacing)*-1.5)}.right-0{right:calc(var(--spacing)*0)}.right-1{right:calc(var(--spacing)*1)}.right-1\.5{right:calc(var(--spacing)*1.5)}.right-2{right:calc(var(--spacing)*2)}.right-3{right:calc(var(--spacing)*3)}.right-4{right:calc(var(--spacing)*4)}.right-6{right:calc(var(--spacing)*6)}.right-12{right:calc(var(--spacing)*12)}.right-full{right:100%}.bottom-0{bottom:calc(var(--spacing)*0)}.bottom-1{bottom:calc(var(--spacing)*1)}.bottom-2{bottom:calc(var(--spacing)*2)}.bottom-4{bottom:calc(var(--spacing)*4)}.bottom-6{bottom:calc(var(--spacing)*6)}.bottom-8{bottom:calc(var(--spacing)*8)}.bottom-full{bottom:100%}.left-0{left:calc(var(--spacing)*0)}.left-1{left:calc(var(--spacing)*1)}.left-1\/2{left:50%}.left-2{left:calc(var(--spacing)*2)}.left-2\.5{left:calc(var(--spacing)*2.5)}.left-3{left:calc(var(--spacing)*3)}.left-4{left:calc(var(--spacing)*4)}.left-10{left:calc(var(--spacing)*10)}.left-12{left:calc(var(--spacing)*12)}.left-\[2px\]{left:2px}.left-\[3px\]{left:3px}.left-full{left:100%}.z-0{z-index:0}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.z-60,.z-\[60\]{z-index:60}.z-\[100\]{z-index:100}.col-span-1{grid-column:span 1/span 1}.col-span-2{grid-column:span 2/span 2}.col-span-3{grid-column:span 3/span 3}.col-span-4{grid-column:span 4/span 4}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.-mx-4{margin-inline:calc(var(--spacing)*-4)}.mx-1{margin-inline:calc(var(--spacing)*1)}.mx-2{margin-inline:calc(var(--spacing)*2)}.mx-4{margin-inline:calc(var(--spacing)*4)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing)*1)}.my-8{margin-block:calc(var(--spacing)*8)}.-mt-2{margin-top:calc(var(--spacing)*-2)}.mt-0\.5{margin-top:calc(var(--spacing)*.5)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-1\.5{margin-top:calc(var(--spacing)*1.5)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-6{margin-top:calc(var(--spacing)*6)}.mt-8{margin-top:calc(var(--spacing)*8)}.mt-14{margin-top:calc(var(--spacing)*14)}.mr-1{margin-right:calc(var(--spacing)*1)}.mr-2{margin-right:calc(var(--spacing)*2)}.mr-3{margin-right:calc(var(--spacing)*3)}.mr-4{margin-right:calc(var(--spacing)*4)}.-mb-px{margin-bottom:-1px}.mb-0\.5{margin-bottom:calc(var(--spacing)*.5)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-1\.5{margin-bottom:calc(var(--spacing)*1.5)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-5{margin-bottom:calc(var(--spacing)*5)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.-ml-1{margin-left:calc(var(--spacing)*-1)}.-ml-2{margin-left:calc(var(--spacing)*-2)}.ml-0\.5{margin-left:calc(var(--spacing)*.5)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-1\.5{margin-left:calc(var(--spacing)*1.5)}.ml-2{margin-left:calc(var(--spacing)*2)}.ml-3{margin-left:calc(var(--spacing)*3)}.ml-4{margin-left:calc(var(--spacing)*4)}.ml-14{margin-left:calc(var(--spacing)*14)}.ml-16{margin-left:calc(var(--spacing)*16)}.ml-64{margin-left:calc(var(--spacing)*64)}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.aspect-square{aspect-ratio:1}.aspect-video{aspect-ratio:var(--aspect-video)}.h-0{height:calc(var(--spacing)*0)}.h-0\.5{height:calc(var(--spacing)*.5)}.h-1{height:calc(var(--spacing)*1)}.h-1\.5{height:calc(var(--spacing)*1.5)}.h-2{height:calc(var(--spacing)*2)}.h-2\.5{height:calc(var(--spacing)*2.5)}.h-3{height:calc(var(--spacing)*3)}.h-3\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-10{height:calc(var(--spacing)*10)}.h-12{height:calc(var(--spacing)*12)}.h-14{height:calc(var(--spacing)*14)}.h-16{height:calc(var(--spacing)*16)}.h-20{height:calc(var(--spacing)*20)}.h-48{height:calc(var(--spacing)*48)}.h-64{height:calc(var(--spacing)*64)}.h-80{height:calc(var(--spacing)*80)}.h-\[18px\]{height:18px}.h-\[80vh\]{height:80vh}.h-\[160px\]{height:160px}.h-\[300px\]{height:300px}.h-\[calc\(100\%-40px\)\]{height:calc(100% - 40px)}.h-\[calc\(100vh-64px\)\]{height:calc(100vh - 64px)}.h-full{height:100%}.h-px{height:1px}.max-h-40{max-height:calc(var(--spacing)*40)}.max-h-48{max-height:calc(var(--spacing)*48)}.max-h-60{max-height:calc(var(--spacing)*60)}.max-h-64{max-height:calc(var(--spacing)*64)}.max-h-80{max-height:calc(var(--spacing)*80)}.max-h-96{max-height:calc(var(--spacing)*96)}.max-h-\[60vh\]{max-height:60vh}.max-h-\[80vh\]{max-height:80vh}.max-h-\[85vh\]{max-height:85vh}.max-h-\[90vh\]{max-height:90vh}.max-h-\[300px\]{max-height:300px}.max-h-\[400px\]{max-height:400px}.max-h-\[500px\]{max-height:500px}.max-h-\[calc\(90vh-80px\)\]{max-height:calc(90vh - 80px)}.max-h-\[calc\(100vh-320px\)\]{max-height:calc(100vh - 320px)}.max-h-full{max-height:100%}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-\[44px\]{min-height:44px}.min-h-\[48px\]{min-height:48px}.min-h-\[120px\]{min-height:120px}.min-h-\[300px\]{min-height:300px}.min-h-\[400px\]{min-height:400px}.min-h-full{min-height:100%}.min-h-screen{min-height:100vh}.w-0{width:calc(var(--spacing)*0)}.w-0\.5{width:calc(var(--spacing)*.5)}.w-1\.5{width:calc(var(--spacing)*1.5)}.w-1\/3{width:33.3333%}.w-2{width:calc(var(--spacing)*2)}.w-2\.5{width:calc(var(--spacing)*2.5)}.w-3{width:calc(var(--spacing)*3)}.w-3\.5{width:calc(var(--spacing)*3.5)}.w-4{width:calc(var(--spacing)*4)}.w-4\.5{width:calc(var(--spacing)*4.5)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-7{width:calc(var(--spacing)*7)}.w-8{width:calc(var(--spacing)*8)}.w-9{width:calc(var(--spacing)*9)}.w-10{width:calc(var(--spacing)*10)}.w-11{width:calc(var(--spacing)*11)}.w-12{width:calc(var(--spacing)*12)}.w-14{width:calc(var(--spacing)*14)}.w-16{width:calc(var(--spacing)*16)}.w-20{width:calc(var(--spacing)*20)}.w-24{width:calc(var(--spacing)*24)}.w-32{width:calc(var(--spacing)*32)}.w-36{width:calc(var(--spacing)*36)}.w-40{width:calc(var(--spacing)*40)}.w-48{width:calc(var(--spacing)*48)}.w-52{width:calc(var(--spacing)*52)}.w-56{width:calc(var(--spacing)*56)}.w-64{width:calc(var(--spacing)*64)}.w-72{width:calc(var(--spacing)*72)}.w-\[560px\]{width:560px}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-32{max-width:calc(var(--spacing)*32)}.max-w-\[40\%\]{max-width:40%}.max-w-\[80px\]{max-width:80px}.max-w-\[90vw\]{max-width:90vw}.max-w-\[100px\]{max-width:100px}.max-w-\[120px\]{max-width:120px}.max-w-\[150px\]{max-width:150px}.max-w-\[160px\]{max-width:160px}.max-w-\[200px\]{max-width:200px}.max-w-\[280px\]{max-width:280px}.max-w-full{max-width:100%}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.max-w-sm{max-width:var(--container-sm)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-48{min-width:calc(var(--spacing)*48)}.min-w-\[16px\]{min-width:16px}.min-w-\[18px\]{min-width:18px}.min-w-\[32px\]{min-width:32px}.min-w-\[48px\]{min-width:48px}.min-w-\[80px\]{min-width:80px}.min-w-\[100px\]{min-width:100px}.min-w-\[120px\]{min-width:120px}.min-w-\[140px\]{min-width:140px}.min-w-\[150px\]{min-width:150px}.min-w-\[160px\]{min-width:160px}.min-w-\[180px\]{min-width:180px}.min-w-full{min-width:100%}.flex-1{flex:1}.flex-shrink{flex-shrink:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-x-full{--tw-translate-x:-100%;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-0{--tw-translate-x:calc(var(--spacing)*0);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-0\.5{--tw-translate-x:calc(var(--spacing)*.5);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-3\.5{--tw-translate-x:calc(var(--spacing)*3.5);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-4{--tw-translate-x:calc(var(--spacing)*4);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-5{--tw-translate-x:calc(var(--spacing)*5);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-6{--tw-translate-x:calc(var(--spacing)*6);translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.scale-110{--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x)var(--tw-scale-y)}.scale-\[1\.02\]{scale:1.02}.-rotate-90{rotate:-90deg}.rotate-90{rotate:90deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-col-resize{cursor:col-resize}.cursor-default{cursor:default}.cursor-ew-resize{cursor:ew-resize}.cursor-grab{cursor:grab}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.cursor-se-resize{cursor:se-resize}.touch-manipulation{touch-action:manipulation}.resize{resize:both}.resize-none{resize:none}.resize-y{resize:vertical}.list-inside{list-style-position:inside}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.appearance-none{appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.grid-cols-\[auto_1fr_100px_100px_100px_80px\]{grid-template-columns:auto 1fr 100px 100px 100px 80px}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing)*.5)}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}.gap-8{gap:calc(var(--spacing)*8)}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*8)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*8)*calc(1 - var(--tw-space-y-reverse)))}.gap-x-6{column-gap:calc(var(--spacing)*6)}.gap-y-1{row-gap:calc(var(--spacing)*1)}.gap-y-3{row-gap:calc(var(--spacing)*3)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px*var(--tw-divide-y-reverse));border-bottom-width:calc(1px*calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-bambu-dark-tertiary>:not(:last-child)),:where(.divide-bambu-dark-tertiary\/30>:not(:last-child)){border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){:where(.divide-bambu-dark-tertiary\/30>:not(:last-child)){border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)30%,transparent)}}:where(.divide-bambu-gray\/20>:not(:last-child)){border-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){:where(.divide-bambu-gray\/20>:not(:last-child)){border-color:color-mix(in oklab,var(--color-bambu-gray)20%,transparent)}}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-t-lg{border-top-left-radius:var(--radius-lg);border-top-right-radius:var(--radius-lg)}.rounded-t-xl{border-top-left-radius:var(--radius-xl);border-top-right-radius:var(--radius-xl)}.\!rounded-l-none{border-top-left-radius:0!important;border-bottom-left-radius:0!important}.rounded-l{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.rounded-l-lg{border-top-left-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}.rounded-tl{border-top-left-radius:.25rem}.\!rounded-r-none{border-top-right-radius:0!important;border-bottom-right-radius:0!important}.rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.rounded-r-lg{border-top-right-radius:var(--radius-lg);border-bottom-right-radius:var(--radius-lg)}.rounded-b-lg{border-bottom-right-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-4{border-style:var(--tw-border-style);border-width:4px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-t-\[5px\]{border-top-style:var(--tw-border-style);border-top-width:5px}.border-t-\[6px\]{border-top-style:var(--tw-border-style);border-top-width:6px}.\!border-r-0{border-right-style:var(--tw-border-style)!important;border-right-width:0!important}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-r-\[5px\]{border-right-style:var(--tw-border-style);border-right-width:5px}.border-r-\[6px\]{border-right-style:var(--tw-border-style);border-right-width:6px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-b-\[6px\]{border-bottom-style:var(--tw-border-style);border-bottom-width:6px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-l-\[5px\]{border-left-style:var(--tw-border-style);border-left-width:5px}.border-l-\[6px\]{border-left-style:var(--tw-border-style);border-left-width:6px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.\!border-green-500{border-color:var(--color-green-500)!important}.border-amber-500\/20{border-color:#f99c0033}@supports (color:color-mix(in lab,red,red)){.border-amber-500\/20{border-color:color-mix(in oklab,var(--color-amber-500)20%,transparent)}}.border-amber-500\/30{border-color:#f99c004d}@supports (color:color-mix(in lab,red,red)){.border-amber-500\/30{border-color:color-mix(in oklab,var(--color-amber-500)30%,transparent)}}.border-bambu-dark-tertiary,.border-bambu-dark-tertiary\/30{border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.border-bambu-dark-tertiary\/30{border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)30%,transparent)}}.border-bambu-dark-tertiary\/50{border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.border-bambu-dark-tertiary\/50{border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)50%,transparent)}}.border-bambu-gray,.border-bambu-gray\/30{border-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.border-bambu-gray\/30{border-color:color-mix(in oklab,var(--color-bambu-gray)30%,transparent)}}.border-bambu-gray\/50{border-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.border-bambu-gray\/50{border-color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.border-bambu-green,.border-bambu-green\/20{border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.border-bambu-green\/20{border-color:color-mix(in oklab,var(--color-bambu-green)20%,transparent)}}.border-bambu-green\/30{border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.border-bambu-green\/30{border-color:color-mix(in oklab,var(--color-bambu-green)30%,transparent)}}.border-bambu-green\/50{border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.border-bambu-green\/50{border-color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.border-blue-400\/20{border-color:#54a2ff33}@supports (color:color-mix(in lab,red,red)){.border-blue-400\/20{border-color:color-mix(in oklab,var(--color-blue-400)20%,transparent)}}.border-blue-500\/20{border-color:#3080ff33}@supports (color:color-mix(in lab,red,red)){.border-blue-500\/20{border-color:color-mix(in oklab,var(--color-blue-500)20%,transparent)}}.border-blue-500\/30{border-color:#3080ff4d}@supports (color:color-mix(in lab,red,red)){.border-blue-500\/30{border-color:color-mix(in oklab,var(--color-blue-500)30%,transparent)}}.border-blue-500\/50{border-color:#3080ff80}@supports (color:color-mix(in lab,red,red)){.border-blue-500\/50{border-color:color-mix(in oklab,var(--color-blue-500)50%,transparent)}}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.border-gray-400\/20{border-color:#99a1af33}@supports (color:color-mix(in lab,red,red)){.border-gray-400\/20{border-color:color-mix(in oklab,var(--color-gray-400)20%,transparent)}}.border-gray-500\/20{border-color:#6a728233}@supports (color:color-mix(in lab,red,red)){.border-gray-500\/20{border-color:color-mix(in oklab,var(--color-gray-500)20%,transparent)}}.border-gray-700{border-color:var(--color-gray-700)}.border-green-300{border-color:var(--color-green-300)}.border-green-500\/30{border-color:#00c7584d}@supports (color:color-mix(in lab,red,red)){.border-green-500\/30{border-color:color-mix(in oklab,var(--color-green-500)30%,transparent)}}.border-green-500\/50{border-color:#00c75880}@supports (color:color-mix(in lab,red,red)){.border-green-500\/50{border-color:color-mix(in oklab,var(--color-green-500)50%,transparent)}}.border-orange-400\/20{border-color:#ff8b1a33}@supports (color:color-mix(in lab,red,red)){.border-orange-400\/20{border-color:color-mix(in oklab,var(--color-orange-400)20%,transparent)}}.border-orange-400\/50{border-color:#ff8b1a80}@supports (color:color-mix(in lab,red,red)){.border-orange-400\/50{border-color:color-mix(in oklab,var(--color-orange-400)50%,transparent)}}.border-orange-500\/20{border-color:#fe6e0033}@supports (color:color-mix(in lab,red,red)){.border-orange-500\/20{border-color:color-mix(in oklab,var(--color-orange-500)20%,transparent)}}.border-orange-500\/30{border-color:#fe6e004d}@supports (color:color-mix(in lab,red,red)){.border-orange-500\/30{border-color:color-mix(in oklab,var(--color-orange-500)30%,transparent)}}.border-purple-400\/20{border-color:#c07eff33}@supports (color:color-mix(in lab,red,red)){.border-purple-400\/20{border-color:color-mix(in oklab,var(--color-purple-400)20%,transparent)}}.border-purple-500\/20{border-color:#ac4bff33}@supports (color:color-mix(in lab,red,red)){.border-purple-500\/20{border-color:color-mix(in oklab,var(--color-purple-500)20%,transparent)}}.border-red-300{border-color:var(--color-red-300)}.border-red-500{border-color:var(--color-red-500)}.border-red-500\/20{border-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.border-red-500\/20{border-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.border-red-500\/30{border-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.border-red-500\/30{border-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.border-red-500\/50{border-color:#fb2c3680}@supports (color:color-mix(in lab,red,red)){.border-red-500\/50{border-color:color-mix(in oklab,var(--color-red-500)50%,transparent)}}.border-status-error\/20{border-color:var(--color-status-error)}@supports (color:color-mix(in lab,red,red)){.border-status-error\/20{border-color:color-mix(in oklab,var(--color-status-error)20%,transparent)}}.border-status-ok,.border-status-ok\/20{border-color:var(--color-status-ok)}@supports (color:color-mix(in lab,red,red)){.border-status-ok\/20{border-color:color-mix(in oklab,var(--color-status-ok)20%,transparent)}}.border-status-warning\/20{border-color:var(--color-status-warning)}@supports (color:color-mix(in lab,red,red)){.border-status-warning\/20{border-color:color-mix(in oklab,var(--color-status-warning)20%,transparent)}}.border-transparent{border-color:#0000}.border-white\/10{border-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.border-white\/10{border-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.border-white\/20{border-color:#fff3}@supports (color:color-mix(in lab,red,red)){.border-white\/20{border-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.border-white\/30{border-color:#ffffff4d}@supports (color:color-mix(in lab,red,red)){.border-white\/30{border-color:color-mix(in oklab,var(--color-white)30%,transparent)}}.border-yellow-400\/50{border-color:#fac80080}@supports (color:color-mix(in lab,red,red)){.border-yellow-400\/50{border-color:color-mix(in oklab,var(--color-yellow-400)50%,transparent)}}.border-yellow-500{border-color:var(--color-yellow-500)}.border-yellow-500\/20{border-color:#edb20033}@supports (color:color-mix(in lab,red,red)){.border-yellow-500\/20{border-color:color-mix(in oklab,var(--color-yellow-500)20%,transparent)}}.border-yellow-500\/30{border-color:#edb2004d}@supports (color:color-mix(in lab,red,red)){.border-yellow-500\/30{border-color:color-mix(in oklab,var(--color-yellow-500)30%,transparent)}}.border-yellow-500\/50{border-color:#edb20080}@supports (color:color-mix(in lab,red,red)){.border-yellow-500\/50{border-color:color-mix(in oklab,var(--color-yellow-500)50%,transparent)}}.border-t-bambu-dark-tertiary{border-top-color:var(--color-bambu-dark-tertiary)}.border-t-transparent{border-top-color:#0000}.border-r-transparent{border-right-color:#0000}.border-b-bambu-dark-tertiary{border-bottom-color:var(--color-bambu-dark-tertiary)}.border-l-transparent{border-left-color:#0000}.border-l-yellow-500{border-left-color:var(--color-yellow-500)}.bg-amber-50{background-color:var(--color-amber-50)}.bg-amber-500{background-color:var(--color-amber-500)}.bg-amber-500\/5{background-color:#f99c000d}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/5{background-color:color-mix(in oklab,var(--color-amber-500)5%,transparent)}}.bg-amber-500\/10{background-color:#f99c001a}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/10{background-color:color-mix(in oklab,var(--color-amber-500)10%,transparent)}}.bg-amber-500\/20{background-color:#f99c0033}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/20{background-color:color-mix(in oklab,var(--color-amber-500)20%,transparent)}}.bg-amber-600\/20{background-color:#dd740033}@supports (color:color-mix(in lab,red,red)){.bg-amber-600\/20{background-color:color-mix(in oklab,var(--color-amber-600)20%,transparent)}}.bg-bambu-dark{background-color:var(--color-bambu-dark)}.bg-bambu-dark-secondary,.bg-bambu-dark-secondary\/30{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-secondary\/30{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)30%,transparent)}}.bg-bambu-dark-secondary\/50{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-secondary\/50{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)50%,transparent)}}.bg-bambu-dark-secondary\/90{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-secondary\/90{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)90%,transparent)}}.bg-bambu-dark-secondary\/95{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-secondary\/95{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)95%,transparent)}}.bg-bambu-dark-tertiary,.bg-bambu-dark-tertiary\/30{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-tertiary\/30{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)30%,transparent)}}.bg-bambu-dark-tertiary\/50{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-tertiary\/50{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)50%,transparent)}}.bg-bambu-dark-tertiary\/80{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-tertiary\/80{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)80%,transparent)}}.bg-bambu-dark\/20{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/20{background-color:color-mix(in oklab,var(--color-bambu-dark)20%,transparent)}}.bg-bambu-dark\/30{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/30{background-color:color-mix(in oklab,var(--color-bambu-dark)30%,transparent)}}.bg-bambu-dark\/50{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/50{background-color:color-mix(in oklab,var(--color-bambu-dark)50%,transparent)}}.bg-bambu-dark\/80{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/80{background-color:color-mix(in oklab,var(--color-bambu-dark)80%,transparent)}}.bg-bambu-dark\/90{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/90{background-color:color-mix(in oklab,var(--color-bambu-dark)90%,transparent)}}.bg-bambu-gray\/10{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/10{background-color:color-mix(in oklab,var(--color-bambu-gray)10%,transparent)}}.bg-bambu-gray\/20{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/20{background-color:color-mix(in oklab,var(--color-bambu-gray)20%,transparent)}}.bg-bambu-gray\/30{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/30{background-color:color-mix(in oklab,var(--color-bambu-gray)30%,transparent)}}.bg-bambu-gray\/90{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/90{background-color:color-mix(in oklab,var(--color-bambu-gray)90%,transparent)}}.bg-bambu-green,.bg-bambu-green\/5{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/5{background-color:color-mix(in oklab,var(--color-bambu-green)5%,transparent)}}.bg-bambu-green\/10{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/10{background-color:color-mix(in oklab,var(--color-bambu-green)10%,transparent)}}.bg-bambu-green\/20{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/20{background-color:color-mix(in oklab,var(--color-bambu-green)20%,transparent)}}.bg-bambu-green\/30{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/30{background-color:color-mix(in oklab,var(--color-bambu-green)30%,transparent)}}.bg-bambu-green\/50{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/50{background-color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.bg-bambu-green\/75{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/75{background-color:color-mix(in oklab,var(--color-bambu-green)75%,transparent)}}.bg-bambu-green\/90{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/90{background-color:color-mix(in oklab,var(--color-bambu-green)90%,transparent)}}.bg-black{background-color:var(--color-black)}.bg-black\/30{background-color:#0000004d}@supports (color:color-mix(in lab,red,red)){.bg-black\/30{background-color:color-mix(in oklab,var(--color-black)30%,transparent)}}.bg-black\/40{background-color:#0006}@supports (color:color-mix(in lab,red,red)){.bg-black\/40{background-color:color-mix(in oklab,var(--color-black)40%,transparent)}}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab,red,red)){.bg-black\/50{background-color:color-mix(in oklab,var(--color-black)50%,transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab,red,red)){.bg-black\/60{background-color:color-mix(in oklab,var(--color-black)60%,transparent)}}.bg-black\/70{background-color:#000000b3}@supports (color:color-mix(in lab,red,red)){.bg-black\/70{background-color:color-mix(in oklab,var(--color-black)70%,transparent)}}.bg-black\/80{background-color:#000c}@supports (color:color-mix(in lab,red,red)){.bg-black\/80{background-color:color-mix(in oklab,var(--color-black)80%,transparent)}}.bg-black\/90{background-color:#000000e6}@supports (color:color-mix(in lab,red,red)){.bg-black\/90{background-color:color-mix(in oklab,var(--color-black)90%,transparent)}}.bg-blue-50{background-color:var(--color-blue-50)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-400{background-color:var(--color-blue-400)}.bg-blue-400\/10{background-color:#54a2ff1a}@supports (color:color-mix(in lab,red,red)){.bg-blue-400\/10{background-color:color-mix(in oklab,var(--color-blue-400)10%,transparent)}}.bg-blue-500{background-color:var(--color-blue-500)}.bg-blue-500\/10{background-color:#3080ff1a}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/10{background-color:color-mix(in oklab,var(--color-blue-500)10%,transparent)}}.bg-blue-500\/20{background-color:#3080ff33}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/20{background-color:color-mix(in oklab,var(--color-blue-500)20%,transparent)}}.bg-blue-500\/30{background-color:#3080ff4d}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/30{background-color:color-mix(in oklab,var(--color-blue-500)30%,transparent)}}.bg-blue-500\/90{background-color:#3080ffe6}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/90{background-color:color-mix(in oklab,var(--color-blue-500)90%,transparent)}}.bg-blue-600{background-color:var(--color-blue-600)}.bg-blue-600\/20{background-color:#155dfc33}@supports (color:color-mix(in lab,red,red)){.bg-blue-600\/20{background-color:color-mix(in oklab,var(--color-blue-600)20%,transparent)}}.bg-cyan-500\/10{background-color:#00b7d71a}@supports (color:color-mix(in lab,red,red)){.bg-cyan-500\/10{background-color:color-mix(in oklab,var(--color-cyan-500)10%,transparent)}}.bg-cyan-500\/20{background-color:#00b7d733}@supports (color:color-mix(in lab,red,red)){.bg-cyan-500\/20{background-color:color-mix(in oklab,var(--color-cyan-500)20%,transparent)}}.bg-cyan-600\/20{background-color:#0092b533}@supports (color:color-mix(in lab,red,red)){.bg-cyan-600\/20{background-color:color-mix(in oklab,var(--color-cyan-600)20%,transparent)}}.bg-emerald-500\/20{background-color:#00bb7f33}@supports (color:color-mix(in lab,red,red)){.bg-emerald-500\/20{background-color:color-mix(in oklab,var(--color-emerald-500)20%,transparent)}}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-400{background-color:var(--color-gray-400)}.bg-gray-400\/10{background-color:#99a1af1a}@supports (color:color-mix(in lab,red,red)){.bg-gray-400\/10{background-color:color-mix(in oklab,var(--color-gray-400)10%,transparent)}}.bg-gray-500{background-color:var(--color-gray-500)}.bg-gray-500\/20{background-color:#6a728233}@supports (color:color-mix(in lab,red,red)){.bg-gray-500\/20{background-color:color-mix(in oklab,var(--color-gray-500)20%,transparent)}}.bg-gray-900{background-color:var(--color-gray-900)}.bg-green-100{background-color:var(--color-green-100)}.bg-green-400{background-color:var(--color-green-400)}.bg-green-500{background-color:var(--color-green-500)}.bg-green-500\/10{background-color:#00c7581a}@supports (color:color-mix(in lab,red,red)){.bg-green-500\/10{background-color:color-mix(in oklab,var(--color-green-500)10%,transparent)}}.bg-green-500\/20{background-color:#00c75833}@supports (color:color-mix(in lab,red,red)){.bg-green-500\/20{background-color:color-mix(in oklab,var(--color-green-500)20%,transparent)}}.bg-indigo-500\/20{background-color:#625fff33}@supports (color:color-mix(in lab,red,red)){.bg-indigo-500\/20{background-color:color-mix(in oklab,var(--color-indigo-500)20%,transparent)}}.bg-orange-400\/10{background-color:#ff8b1a1a}@supports (color:color-mix(in lab,red,red)){.bg-orange-400\/10{background-color:color-mix(in oklab,var(--color-orange-400)10%,transparent)}}.bg-orange-500{background-color:var(--color-orange-500)}.bg-orange-500\/10{background-color:#fe6e001a}@supports (color:color-mix(in lab,red,red)){.bg-orange-500\/10{background-color:color-mix(in oklab,var(--color-orange-500)10%,transparent)}}.bg-orange-500\/20{background-color:#fe6e0033}@supports (color:color-mix(in lab,red,red)){.bg-orange-500\/20{background-color:color-mix(in oklab,var(--color-orange-500)20%,transparent)}}.bg-orange-600{background-color:var(--color-orange-600)}.bg-orange-600\/20{background-color:#f0510033}@supports (color:color-mix(in lab,red,red)){.bg-orange-600\/20{background-color:color-mix(in oklab,var(--color-orange-600)20%,transparent)}}.bg-purple-400\/10{background-color:#c07eff1a}@supports (color:color-mix(in lab,red,red)){.bg-purple-400\/10{background-color:color-mix(in oklab,var(--color-purple-400)10%,transparent)}}.bg-purple-500\/10{background-color:#ac4bff1a}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/10{background-color:color-mix(in oklab,var(--color-purple-500)10%,transparent)}}.bg-purple-500\/20{background-color:#ac4bff33}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/20{background-color:color-mix(in oklab,var(--color-purple-500)20%,transparent)}}.bg-purple-500\/80{background-color:#ac4bffcc}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/80{background-color:color-mix(in oklab,var(--color-purple-500)80%,transparent)}}.bg-purple-500\/90{background-color:#ac4bffe6}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/90{background-color:color-mix(in oklab,var(--color-purple-500)90%,transparent)}}.bg-red-50{background-color:var(--color-red-50)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-400{background-color:var(--color-red-400)}.bg-red-500{background-color:var(--color-red-500)}.bg-red-500\/5{background-color:#fb2c360d}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/5{background-color:color-mix(in oklab,var(--color-red-500)5%,transparent)}}.bg-red-500\/10{background-color:#fb2c361a}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/10{background-color:color-mix(in oklab,var(--color-red-500)10%,transparent)}}.bg-red-500\/15{background-color:#fb2c3626}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/15{background-color:color-mix(in oklab,var(--color-red-500)15%,transparent)}}.bg-red-500\/20{background-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/20{background-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.bg-red-500\/30{background-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/30{background-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.bg-red-500\/40{background-color:#fb2c3666}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/40{background-color:color-mix(in oklab,var(--color-red-500)40%,transparent)}}.bg-red-500\/80{background-color:#fb2c36cc}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/80{background-color:color-mix(in oklab,var(--color-red-500)80%,transparent)}}.bg-red-600{background-color:var(--color-red-600)}.bg-rose-500\/20{background-color:#ff235733}@supports (color:color-mix(in lab,red,red)){.bg-rose-500\/20{background-color:color-mix(in oklab,var(--color-rose-500)20%,transparent)}}.bg-rose-600\/20{background-color:#e7004433}@supports (color:color-mix(in lab,red,red)){.bg-rose-600\/20{background-color:color-mix(in oklab,var(--color-rose-600)20%,transparent)}}.bg-status-error,.bg-status-error\/10{background-color:var(--color-status-error)}@supports (color:color-mix(in lab,red,red)){.bg-status-error\/10{background-color:color-mix(in oklab,var(--color-status-error)10%,transparent)}}.bg-status-error\/20{background-color:var(--color-status-error)}@supports (color:color-mix(in lab,red,red)){.bg-status-error\/20{background-color:color-mix(in oklab,var(--color-status-error)20%,transparent)}}.bg-status-error\/80{background-color:var(--color-status-error)}@supports (color:color-mix(in lab,red,red)){.bg-status-error\/80{background-color:color-mix(in oklab,var(--color-status-error)80%,transparent)}}.bg-status-ok,.bg-status-ok\/10{background-color:var(--color-status-ok)}@supports (color:color-mix(in lab,red,red)){.bg-status-ok\/10{background-color:color-mix(in oklab,var(--color-status-ok)10%,transparent)}}.bg-status-ok\/20{background-color:var(--color-status-ok)}@supports (color:color-mix(in lab,red,red)){.bg-status-ok\/20{background-color:color-mix(in oklab,var(--color-status-ok)20%,transparent)}}.bg-status-warning\/10{background-color:var(--color-status-warning)}@supports (color:color-mix(in lab,red,red)){.bg-status-warning\/10{background-color:color-mix(in oklab,var(--color-status-warning)10%,transparent)}}.bg-status-warning\/20{background-color:var(--color-status-warning)}@supports (color:color-mix(in lab,red,red)){.bg-status-warning\/20{background-color:color-mix(in oklab,var(--color-status-warning)20%,transparent)}}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-white\/50{background-color:#ffffff80}@supports (color:color-mix(in lab,red,red)){.bg-white\/50{background-color:color-mix(in oklab,var(--color-white)50%,transparent)}}.bg-white\/70{background-color:#ffffffb3}@supports (color:color-mix(in lab,red,red)){.bg-white\/70{background-color:color-mix(in oklab,var(--color-white)70%,transparent)}}.bg-white\/90{background-color:#ffffffe6}@supports (color:color-mix(in lab,red,red)){.bg-white\/90{background-color:color-mix(in oklab,var(--color-white)90%,transparent)}}.bg-yellow-400{background-color:var(--color-yellow-400)}.bg-yellow-400\/20{background-color:#fac80033}@supports (color:color-mix(in lab,red,red)){.bg-yellow-400\/20{background-color:color-mix(in oklab,var(--color-yellow-400)20%,transparent)}}.bg-yellow-500{background-color:var(--color-yellow-500)}.bg-yellow-500\/5{background-color:#edb2000d}@supports (color:color-mix(in lab,red,red)){.bg-yellow-500\/5{background-color:color-mix(in oklab,var(--color-yellow-500)5%,transparent)}}.bg-yellow-500\/10{background-color:#edb2001a}@supports (color:color-mix(in lab,red,red)){.bg-yellow-500\/10{background-color:color-mix(in oklab,var(--color-yellow-500)10%,transparent)}}.bg-yellow-500\/20{background-color:#edb20033}@supports (color:color-mix(in lab,red,red)){.bg-yellow-500\/20{background-color:color-mix(in oklab,var(--color-yellow-500)20%,transparent)}}.bg-gradient-to-b{--tw-gradient-position:to bottom in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-r{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-t{--tw-gradient-position:to top in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-bambu-green\/10{--tw-gradient-from:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.from-bambu-green\/10{--tw-gradient-from:color-mix(in oklab,var(--color-bambu-green)10%,transparent)}}.from-bambu-green\/10{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-black\/80{--tw-gradient-from:#000c}@supports (color:color-mix(in lab,red,red)){.from-black\/80{--tw-gradient-from:color-mix(in oklab,var(--color-black)80%,transparent)}}.from-black\/80{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-blue-500{--tw-gradient-from:var(--color-blue-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-blue-500\/5{--tw-gradient-from:#3080ff0d}@supports (color:color-mix(in lab,red,red)){.from-blue-500\/5{--tw-gradient-from:color-mix(in oklab,var(--color-blue-500)5%,transparent)}}.from-blue-500\/5{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-blue-500\/10{--tw-gradient-from:#3080ff1a}@supports (color:color-mix(in lab,red,red)){.from-blue-500\/10{--tw-gradient-from:color-mix(in oklab,var(--color-blue-500)10%,transparent)}}.from-blue-500\/10{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-gray-500\/10{--tw-gradient-from:#6a72821a}@supports (color:color-mix(in lab,red,red)){.from-gray-500\/10{--tw-gradient-from:color-mix(in oklab,var(--color-gray-500)10%,transparent)}}.from-gray-500\/10{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-white\/10{--tw-gradient-from:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.from-white\/10{--tw-gradient-from:color-mix(in oklab,var(--color-white)10%,transparent)}}.from-white\/10{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-yellow-500\/10{--tw-gradient-from:#edb2001a}@supports (color:color-mix(in lab,red,red)){.from-yellow-500\/10{--tw-gradient-from:color-mix(in oklab,var(--color-yellow-500)10%,transparent)}}.from-yellow-500\/10{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-bambu-dark-secondary{--tw-gradient-to:var(--color-bambu-dark-secondary);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-blue-400{--tw-gradient-to:var(--color-blue-400);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-transparent{--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.bg-cover{background-size:cover}.bg-center{background-position:50%}.fill-yellow-400{fill:var(--color-yellow-400)}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.object-left{object-position:left}.p-0{padding:calc(var(--spacing)*0)}.p-0\.5{padding:calc(var(--spacing)*.5)}.p-1{padding:calc(var(--spacing)*1)}.p-1\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-2\.5{padding:calc(var(--spacing)*2.5)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-5{padding:calc(var(--spacing)*5)}.p-6{padding:calc(var(--spacing)*6)}.p-8{padding:calc(var(--spacing)*8)}.p-12{padding:calc(var(--spacing)*12)}.\!px-1\.5{padding-inline:calc(var(--spacing)*1.5)!important}.\!px-3{padding-inline:calc(var(--spacing)*3)!important}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-6{padding-inline:calc(var(--spacing)*6)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.py-6{padding-block:calc(var(--spacing)*6)}.py-8{padding-block:calc(var(--spacing)*8)}.py-12{padding-block:calc(var(--spacing)*12)}.py-16{padding-block:calc(var(--spacing)*16)}.py-20{padding-block:calc(var(--spacing)*20)}.py-24{padding-block:calc(var(--spacing)*24)}.pt-0{padding-top:calc(var(--spacing)*0)}.pt-1{padding-top:calc(var(--spacing)*1)}.pt-2{padding-top:calc(var(--spacing)*2)}.pt-3{padding-top:calc(var(--spacing)*3)}.pt-4{padding-top:calc(var(--spacing)*4)}.pr-1{padding-right:calc(var(--spacing)*1)}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-3{padding-right:calc(var(--spacing)*3)}.pr-4{padding-right:calc(var(--spacing)*4)}.pr-6{padding-right:calc(var(--spacing)*6)}.pr-8{padding-right:calc(var(--spacing)*8)}.pr-10{padding-right:calc(var(--spacing)*10)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.pb-2{padding-bottom:calc(var(--spacing)*2)}.pb-4{padding-bottom:calc(var(--spacing)*4)}.pl-2{padding-left:calc(var(--spacing)*2)}.pl-4{padding-left:calc(var(--spacing)*4)}.pl-6{padding-left:calc(var(--spacing)*6)}.pl-8{padding-left:calc(var(--spacing)*8)}.pl-9{padding-left:calc(var(--spacing)*9)}.pl-10{padding-left:calc(var(--spacing)*10)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.\!text-green-400{color:var(--color-green-400)!important}.text-amber-200{color:var(--color-amber-200)}.text-amber-300{color:var(--color-amber-300)}.text-amber-300\/60{color:#ffd23699}@supports (color:color-mix(in lab,red,red)){.text-amber-300\/60{color:color-mix(in oklab,var(--color-amber-300)60%,transparent)}}.text-amber-300\/70{color:#ffd236b3}@supports (color:color-mix(in lab,red,red)){.text-amber-300\/70{color:color-mix(in oklab,var(--color-amber-300)70%,transparent)}}.text-amber-300\/80{color:#ffd236cc}@supports (color:color-mix(in lab,red,red)){.text-amber-300\/80{color:color-mix(in oklab,var(--color-amber-300)80%,transparent)}}.text-amber-400{color:var(--color-amber-400)}.text-amber-400\/70{color:#fcbb00b3}@supports (color:color-mix(in lab,red,red)){.text-amber-400\/70{color:color-mix(in oklab,var(--color-amber-400)70%,transparent)}}.text-amber-500{color:var(--color-amber-500)}.text-amber-500\/80{color:#f99c00cc}@supports (color:color-mix(in lab,red,red)){.text-amber-500\/80{color:color-mix(in oklab,var(--color-amber-500)80%,transparent)}}.text-amber-600{color:var(--color-amber-600)}.text-bambu-dark-tertiary{color:var(--color-bambu-dark-tertiary)}.text-bambu-gray{color:var(--color-bambu-gray)}.text-bambu-gray-dark{color:var(--color-bambu-gray-dark)}.text-bambu-gray-light{color:var(--color-bambu-gray-light)}.text-bambu-gray\/30{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/30{color:color-mix(in oklab,var(--color-bambu-gray)30%,transparent)}}.text-bambu-gray\/50{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/50{color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.text-bambu-gray\/60{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/60{color:color-mix(in oklab,var(--color-bambu-gray)60%,transparent)}}.text-bambu-gray\/70{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/70{color:color-mix(in oklab,var(--color-bambu-gray)70%,transparent)}}.text-bambu-gray\/80{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/80{color:color-mix(in oklab,var(--color-bambu-gray)80%,transparent)}}.text-bambu-green,.text-bambu-green\/70{color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.text-bambu-green\/70{color:color-mix(in oklab,var(--color-bambu-green)70%,transparent)}}.text-black{color:var(--color-black)}.text-black\/80{color:#000c}@supports (color:color-mix(in lab,red,red)){.text-black\/80{color:color-mix(in oklab,var(--color-black)80%,transparent)}}.text-blue-300{color:var(--color-blue-300)}.text-blue-300\/70{color:#90c5ffb3}@supports (color:color-mix(in lab,red,red)){.text-blue-300\/70{color:color-mix(in oklab,var(--color-blue-300)70%,transparent)}}.text-blue-300\/80{color:#90c5ffcc}@supports (color:color-mix(in lab,red,red)){.text-blue-300\/80{color:color-mix(in oklab,var(--color-blue-300)80%,transparent)}}.text-blue-400{color:var(--color-blue-400)}.text-blue-500{color:var(--color-blue-500)}.text-blue-500\/70{color:#3080ffb3}@supports (color:color-mix(in lab,red,red)){.text-blue-500\/70{color:color-mix(in oklab,var(--color-blue-500)70%,transparent)}}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-cyan-300{color:var(--color-cyan-300)}.text-cyan-400{color:var(--color-cyan-400)}.text-emerald-400{color:var(--color-emerald-400)}.text-gray-300{color:var(--color-gray-300)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-900{color:var(--color-gray-900)}.text-green-300{color:var(--color-green-300)}.text-green-400{color:var(--color-green-400)}.text-green-500{color:var(--color-green-500)}.text-green-500\/60{color:#00c75899}@supports (color:color-mix(in lab,red,red)){.text-green-500\/60{color:color-mix(in oklab,var(--color-green-500)60%,transparent)}}.text-green-600{color:var(--color-green-600)}.text-indigo-400{color:var(--color-indigo-400)}.text-orange-200{color:var(--color-orange-200)}.text-orange-300{color:var(--color-orange-300)}.text-orange-400{color:var(--color-orange-400)}.text-orange-500{color:var(--color-orange-500)}.text-orange-600{color:var(--color-orange-600)}.text-orange-700{color:var(--color-orange-700)}.text-purple-300{color:var(--color-purple-300)}.text-purple-400{color:var(--color-purple-400)}.text-purple-400\/80{color:#c07effcc}@supports (color:color-mix(in lab,red,red)){.text-purple-400\/80{color:color-mix(in oklab,var(--color-purple-400)80%,transparent)}}.text-red-300{color:var(--color-red-300)}.text-red-300\/80{color:#ffa3a3cc}@supports (color:color-mix(in lab,red,red)){.text-red-300\/80{color:color-mix(in oklab,var(--color-red-300)80%,transparent)}}.text-red-400{color:var(--color-red-400)}.text-red-400\/60{color:#ff656899}@supports (color:color-mix(in lab,red,red)){.text-red-400\/60{color:color-mix(in oklab,var(--color-red-400)60%,transparent)}}.text-red-400\/70{color:#ff6568b3}@supports (color:color-mix(in lab,red,red)){.text-red-400\/70{color:color-mix(in oklab,var(--color-red-400)70%,transparent)}}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-rose-300{color:var(--color-rose-300)}.text-rose-400{color:var(--color-rose-400)}.text-status-error{color:var(--color-status-error)}.text-status-ok{color:var(--color-status-ok)}.text-status-warning{color:var(--color-status-warning)}.text-white{color:var(--color-white)}.text-white\/60{color:#fff9}@supports (color:color-mix(in lab,red,red)){.text-white\/60{color:color-mix(in oklab,var(--color-white)60%,transparent)}}.text-white\/80{color:#fffc}@supports (color:color-mix(in lab,red,red)){.text-white\/80{color:color-mix(in oklab,var(--color-white)80%,transparent)}}.text-white\/90{color:#ffffffe6}@supports (color:color-mix(in lab,red,red)){.text-white\/90{color:color-mix(in oklab,var(--color-white)90%,transparent)}}.text-yellow-200{color:var(--color-yellow-200)}.text-yellow-400{color:var(--color-yellow-400)}.text-yellow-500{color:var(--color-yellow-500)}.text-yellow-500\/70{color:#edb200b3}@supports (color:color-mix(in lab,red,red)){.text-yellow-500\/70{color:color-mix(in oklab,var(--color-yellow-500)70%,transparent)}}.text-yellow-600{color:var(--color-yellow-600)}.text-yellow-700{color:var(--color-yellow-700)}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.underline{text-decoration-line:underline}.placeholder-bambu-gray::placeholder{color:var(--color-bambu-gray)}.placeholder-bambu-gray-dark::placeholder{color:var(--color-bambu-gray-dark)}.placeholder-bambu-gray\/50::placeholder{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.placeholder-bambu-gray\/50::placeholder{color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.accent-bambu-green{accent-color:var(--color-bambu-green)}.accent-green-500{accent-color:var(--color-green-500)}.opacity-0{opacity:0}.opacity-20{opacity:.2}.opacity-30{opacity:.3}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-80{opacity:.8}.opacity-100{opacity:1}.opacity-\[0\.65\]{opacity:.65}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-bambu-green\/20{--tw-shadow-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.shadow-bambu-green\/20{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-bambu-green)20%,transparent)var(--tw-shadow-alpha),transparent)}}.shadow-bambu-green\/25{--tw-shadow-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.shadow-bambu-green\/25{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-bambu-green)25%,transparent)var(--tw-shadow-alpha),transparent)}}.ring-bambu-green{--tw-ring-color:var(--color-bambu-green)}.ring-blue-400\/50{--tw-ring-color:#54a2ff80}@supports (color:color-mix(in lab,red,red)){.ring-blue-400\/50{--tw-ring-color:color-mix(in oklab,var(--color-blue-400)50%,transparent)}}.ring-green-500{--tw-ring-color:var(--color-green-500)}.ring-white{--tw-ring-color:var(--color-white)}.ring-offset-1{--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.ring-offset-2{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.ring-offset-bambu-dark{--tw-ring-offset-color:var(--color-bambu-dark)}.ring-offset-bambu-dark-secondary{--tw-ring-offset-color:var(--color-bambu-dark-secondary)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.invert{--tw-invert:invert(100%);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.group-hover\:bg-bambu-green\/20:is(:where(.group):hover *){background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.group-hover\:bg-bambu-green\/20:is(:where(.group):hover *){background-color:color-mix(in oklab,var(--color-bambu-green)20%,transparent)}}.group-hover\:text-bambu-gray:is(:where(.group):hover *){color:var(--color-bambu-gray)}.group-hover\:text-bambu-green:is(:where(.group):hover *){color:var(--color-bambu-green)}.group-hover\:opacity-50:is(:where(.group):hover *){opacity:.5}.group-hover\:opacity-100:is(:where(.group):hover *),.group-hover\/resize\:opacity-100:is(:where(.group\/resize):hover *){opacity:1}.group-hover\/thumb\:block:is(:where(.group\/thumb):hover *){display:block}}.peer-checked\:bg-bambu-green:is(:where(.peer):checked~*){background-color:var(--color-bambu-green)}.peer-focus\:outline-none:is(:where(.peer):focus~*){--tw-outline-style:none;outline-style:none}.placeholder\:text-bambu-gray::placeholder{color:var(--color-bambu-gray)}.before\:absolute:before{content:var(--tw-content);position:absolute}.before\:top-0:before{content:var(--tw-content);top:calc(var(--spacing)*0)}.before\:right-0:before{content:var(--tw-content);right:calc(var(--spacing)*0)}.before\:left-0:before{content:var(--tw-content);left:calc(var(--spacing)*0)}.before\:h-0\.5:before{content:var(--tw-content);height:calc(var(--spacing)*.5)}.before\:bg-bambu-green:before{content:var(--tw-content);background-color:var(--color-bambu-green)}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:top-\[2px\]:after{content:var(--tw-content);top:2px}.after\:left-\[2px\]:after{content:var(--tw-content);left:2px}.after\:h-4:after{content:var(--tw-content);height:calc(var(--spacing)*4)}.after\:h-5:after{content:var(--tw-content);height:calc(var(--spacing)*5)}.after\:w-4:after{content:var(--tw-content);width:calc(var(--spacing)*4)}.after\:w-5:after{content:var(--tw-content);width:calc(var(--spacing)*5)}.after\:rounded-full:after{content:var(--tw-content);border-radius:3.40282e38px}.after\:border:after{content:var(--tw-content);border-style:var(--tw-border-style);border-width:1px}.after\:border-gray-300:after{content:var(--tw-content);border-color:var(--color-gray-300)}.after\:bg-white:after{content:var(--tw-content);background-color:var(--color-white)}.after\:transition-all:after{content:var(--tw-content);transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.after\:content-\[\'\'\]:after{--tw-content:"";content:var(--tw-content)}.peer-checked\:after\:translate-x-full:is(:where(.peer):checked~*):after{content:var(--tw-content);--tw-translate-x:100%;translate:var(--tw-translate-x)var(--tw-translate-y)}.peer-checked\:after\:border-white:is(:where(.peer):checked~*):after{content:var(--tw-content);border-color:var(--color-white)}.last\:border-0:last-child{border-style:var(--tw-border-style);border-width:0}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}@media(hover:hover){.hover\:border-bambu-dark-tertiary\/80:hover{border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:border-bambu-dark-tertiary\/80:hover{border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)80%,transparent)}}.hover\:border-bambu-gray:hover{border-color:var(--color-bambu-gray)}.hover\:border-bambu-gray-dark:hover{border-color:var(--color-bambu-gray-dark)}.hover\:border-bambu-green:hover,.hover\:border-bambu-green\/50:hover{border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:border-bambu-green\/50:hover{border-color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.hover\:border-white\/40:hover{border-color:#fff6}@supports (color:color-mix(in lab,red,red)){.hover\:border-white\/40:hover{border-color:color-mix(in oklab,var(--color-white)40%,transparent)}}.hover\:\!bg-green-500\/20:hover{background-color:#00c75833!important}@supports (color:color-mix(in lab,red,red)){.hover\:\!bg-green-500\/20:hover{background-color:color-mix(in oklab,var(--color-green-500)20%,transparent)!important}}.hover\:bg-amber-500\/30:hover{background-color:#f99c004d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-amber-500\/30:hover{background-color:color-mix(in oklab,var(--color-amber-500)30%,transparent)}}.hover\:bg-bambu-dark:hover{background-color:var(--color-bambu-dark)}.hover\:bg-bambu-dark-secondary:hover,.hover\:bg-bambu-dark-secondary\/50:hover{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-secondary\/50:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)50%,transparent)}}.hover\:bg-bambu-dark-tertiary:hover,.hover\:bg-bambu-dark-tertiary\/30:hover{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-tertiary\/30:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)30%,transparent)}}.hover\:bg-bambu-dark-tertiary\/50:hover{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-tertiary\/50:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)50%,transparent)}}.hover\:bg-bambu-dark-tertiary\/70:hover{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-tertiary\/70:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)70%,transparent)}}.hover\:bg-bambu-dark-tertiary\/80:hover{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-tertiary\/80:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)80%,transparent)}}.hover\:bg-bambu-dark\/50:hover{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark\/50:hover{background-color:color-mix(in oklab,var(--color-bambu-dark)50%,transparent)}}.hover\:bg-bambu-gray-dark:hover{background-color:var(--color-bambu-gray-dark)}.hover\:bg-bambu-green:hover{background-color:var(--color-bambu-green)}.hover\:bg-bambu-green-dark:hover{background-color:var(--color-bambu-green-dark)}.hover\:bg-bambu-green-light:hover{background-color:var(--color-bambu-green-light)}.hover\:bg-bambu-green\/10:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/10:hover{background-color:color-mix(in oklab,var(--color-bambu-green)10%,transparent)}}.hover\:bg-bambu-green\/20:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/20:hover{background-color:color-mix(in oklab,var(--color-bambu-green)20%,transparent)}}.hover\:bg-bambu-green\/30:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/30:hover{background-color:color-mix(in oklab,var(--color-bambu-green)30%,transparent)}}.hover\:bg-bambu-green\/50:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/50:hover{background-color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.hover\:bg-bambu-green\/80:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/80:hover{background-color:color-mix(in oklab,var(--color-bambu-green)80%,transparent)}}.hover\:bg-black\/40:hover{background-color:#0006}@supports (color:color-mix(in lab,red,red)){.hover\:bg-black\/40:hover{background-color:color-mix(in oklab,var(--color-black)40%,transparent)}}.hover\:bg-black\/70:hover{background-color:#000000b3}@supports (color:color-mix(in lab,red,red)){.hover\:bg-black\/70:hover{background-color:color-mix(in oklab,var(--color-black)70%,transparent)}}.hover\:bg-black\/80:hover{background-color:#000c}@supports (color:color-mix(in lab,red,red)){.hover\:bg-black\/80:hover{background-color:color-mix(in oklab,var(--color-black)80%,transparent)}}.hover\:bg-blue-500\/30:hover{background-color:#3080ff4d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-blue-500\/30:hover{background-color:color-mix(in oklab,var(--color-blue-500)30%,transparent)}}.hover\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-gray-700:hover{background-color:var(--color-gray-700)}.hover\:bg-orange-400\/20:hover{background-color:#ff8b1a33}@supports (color:color-mix(in lab,red,red)){.hover\:bg-orange-400\/20:hover{background-color:color-mix(in oklab,var(--color-orange-400)20%,transparent)}}.hover\:bg-red-200:hover{background-color:var(--color-red-200)}.hover\:bg-red-400\/10:hover{background-color:#ff65681a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-400\/10:hover{background-color:color-mix(in oklab,var(--color-red-400)10%,transparent)}}.hover\:bg-red-500\/10:hover{background-color:#fb2c361a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/10:hover{background-color:color-mix(in oklab,var(--color-red-500)10%,transparent)}}.hover\:bg-red-500\/20:hover{background-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/20:hover{background-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.hover\:bg-red-500\/30:hover{background-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/30:hover{background-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.hover\:bg-red-600:hover{background-color:var(--color-red-600)}.hover\:bg-red-700:hover{background-color:var(--color-red-700)}.hover\:bg-white\/10:hover{background-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/10:hover{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.hover\:bg-yellow-500\/30:hover{background-color:#edb2004d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-yellow-500\/30:hover{background-color:color-mix(in oklab,var(--color-yellow-500)30%,transparent)}}.hover\:bg-yellow-600:hover{background-color:var(--color-yellow-600)}.hover\:text-amber-300:hover{color:var(--color-amber-300)}.hover\:text-bambu-gray:hover{color:var(--color-bambu-gray)}.hover\:text-bambu-green:hover{color:var(--color-bambu-green)}.hover\:text-bambu-green-light:hover{color:var(--color-bambu-green-light)}.hover\:text-bambu-green\/70:hover{color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:text-bambu-green\/70:hover{color:color-mix(in oklab,var(--color-bambu-green)70%,transparent)}}.hover\:text-bambu-green\/80:hover{color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:text-bambu-green\/80:hover{color:color-mix(in oklab,var(--color-bambu-green)80%,transparent)}}.hover\:text-blue-300:hover{color:var(--color-blue-300)}.hover\:text-gray-900:hover{color:var(--color-gray-900)}.hover\:text-orange-300:hover{color:var(--color-orange-300)}.hover\:text-red-300:hover{color:var(--color-red-300)}.hover\:text-red-400:hover{color:var(--color-red-400)}.hover\:text-white:hover{color:var(--color-white)}.hover\:text-white\/80:hover{color:#fffc}@supports (color:color-mix(in lab,red,red)){.hover\:text-white\/80:hover{color:color-mix(in oklab,var(--color-white)80%,transparent)}}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-70:hover{opacity:.7}.hover\:opacity-80:hover{opacity:.8}.hover\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:shadow-bambu-green\/5:hover{--tw-shadow-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:shadow-bambu-green\/5:hover{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-bambu-green)5%,transparent)var(--tw-shadow-alpha),transparent)}}.hover\:shadow-bambu-green\/30:hover{--tw-shadow-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:shadow-bambu-green\/30:hover{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-bambu-green)30%,transparent)var(--tw-shadow-alpha),transparent)}}}.focus\:border-bambu-green:focus{border-color:var(--color-bambu-green)}.focus\:border-red-500:focus{border-color:var(--color-red-500)}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-bambu-gray:focus{--tw-ring-color:var(--color-bambu-gray)}.focus\:ring-bambu-green:focus,.focus\:ring-bambu-green\/50:focus{--tw-ring-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.focus\:ring-bambu-green\/50:focus{--tw-ring-color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.focus\:ring-red-500:focus{--tw-ring-color:var(--color-red-500)}.focus\:ring-offset-0:focus{--tw-ring-offset-width:0px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:ring-offset-bambu-dark:focus{--tw-ring-offset-color:var(--color-bambu-dark)}.focus\:ring-offset-bambu-dark-secondary:focus{--tw-ring-offset-color:var(--color-bambu-dark-secondary)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.active\:cursor-grabbing:active{cursor:grabbing}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-50:disabled{opacity:.5}@media(hover:hover){.disabled\:hover\:bg-bambu-green:disabled:hover{background-color:var(--color-bambu-green)}}@media(min-width:40rem){.sm\:inline{display:inline}.sm\:h-4{height:calc(var(--spacing)*4)}.sm\:w-4{width:calc(var(--spacing)*4)}.sm\:w-auto{width:auto}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:p-1\.5{padding:calc(var(--spacing)*1.5)}}@media(min-width:48rem){.md\:top-\[2px\]{top:2px}.md\:left-\[2px\]{left:2px}.md\:mx-0{margin-inline:calc(var(--spacing)*0)}.md\:block{display:block}.md\:inline{display:inline}.md\:h-4{height:calc(var(--spacing)*4)}.md\:h-5{height:calc(var(--spacing)*5)}.md\:h-8{height:calc(var(--spacing)*8)}.md\:min-h-0{min-height:calc(var(--spacing)*0)}.md\:w-4{width:calc(var(--spacing)*4)}.md\:w-8{width:calc(var(--spacing)*8)}.md\:w-9{width:calc(var(--spacing)*9)}.md\:min-w-\[200px\]{min-width:200px}.md\:flex-1{flex:1}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:flex-wrap{flex-wrap:wrap}.md\:items-center{align-items:center}.md\:gap-4{gap:calc(var(--spacing)*4)}.md\:p-8{padding:calc(var(--spacing)*8)}.md\:px-0{padding-inline:calc(var(--spacing)*0)}.md\:py-2{padding-block:calc(var(--spacing)*2)}.md\:pb-0{padding-bottom:calc(var(--spacing)*0)}.md\:opacity-0{opacity:0}@media(hover:hover){.md\:group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}}@media(min-width:64rem){.lg\:col-span-2{grid-column:span 2/span 2}.lg\:w-80{width:calc(var(--spacing)*80)}.lg\:w-\[480px\]{width:480px}.lg\:max-w-md{max-width:var(--container-md)}.lg\:max-w-sm{max-width:var(--container-sm)}.lg\:max-w-xl{max-width:var(--container-xl)}.lg\:flex-shrink-0{flex-shrink:0}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:gap-8{gap:calc(var(--spacing)*8)}.lg\:p-8{padding:calc(var(--spacing)*8)}}@media(min-width:80rem){.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.xl\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.xl\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}}@media(min-width:96rem){.\32xl\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}}.dark\:border-bambu-dark-tertiary:where(.dark,.dark *),.dark\:border-bambu-dark-tertiary\/50:where(.dark,.dark *){border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.dark\:border-bambu-dark-tertiary\/50:where(.dark,.dark *){border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)50%,transparent)}}.dark\:border-bambu-green\/40:where(.dark,.dark *){border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.dark\:border-bambu-green\/40:where(.dark,.dark *){border-color:color-mix(in oklab,var(--color-bambu-green)40%,transparent)}}.dark\:border-gray-600:where(.dark,.dark *){border-color:var(--color-gray-600)}.dark\:border-red-500\/30:where(.dark,.dark *){border-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.dark\:border-red-500\/30:where(.dark,.dark *){border-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.dark\:border-red-500\/40:where(.dark,.dark *){border-color:#fb2c3666}@supports (color:color-mix(in lab,red,red)){.dark\:border-red-500\/40:where(.dark,.dark *){border-color:color-mix(in oklab,var(--color-red-500)40%,transparent)}}.dark\:bg-amber-500\/10:where(.dark,.dark *){background-color:#f99c001a}@supports (color:color-mix(in lab,red,red)){.dark\:bg-amber-500\/10:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-amber-500)10%,transparent)}}.dark\:bg-bambu-dark:where(.dark,.dark *){background-color:var(--color-bambu-dark)}.dark\:bg-bambu-dark-secondary:where(.dark,.dark *){background-color:var(--color-bambu-dark-secondary)}.dark\:bg-bambu-green\/20:where(.dark,.dark *){background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.dark\:bg-bambu-green\/20:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-bambu-green)20%,transparent)}}.dark\:bg-black\/80:where(.dark,.dark *){background-color:#000c}@supports (color:color-mix(in lab,red,red)){.dark\:bg-black\/80:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-black)80%,transparent)}}.dark\:bg-blue-500\/10:where(.dark,.dark *){background-color:#3080ff1a}@supports (color:color-mix(in lab,red,red)){.dark\:bg-blue-500\/10:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-blue-500)10%,transparent)}}.dark\:bg-blue-500\/20:where(.dark,.dark *){background-color:#3080ff33}@supports (color:color-mix(in lab,red,red)){.dark\:bg-blue-500\/20:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-blue-500)20%,transparent)}}.dark\:bg-gray-500\/40:where(.dark,.dark *){background-color:#6a728266}@supports (color:color-mix(in lab,red,red)){.dark\:bg-gray-500\/40:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-gray-500)40%,transparent)}}.dark\:bg-gray-900:where(.dark,.dark *){background-color:var(--color-gray-900)}.dark\:bg-red-500\/10:where(.dark,.dark *){background-color:#fb2c361a}@supports (color:color-mix(in lab,red,red)){.dark\:bg-red-500\/10:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-red-500)10%,transparent)}}.dark\:bg-red-500\/20:where(.dark,.dark *){background-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.dark\:bg-red-500\/20:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.dark\:text-amber-400:where(.dark,.dark *){color:var(--color-amber-400)}.dark\:text-bambu-gray:where(.dark,.dark *),.dark\:text-bambu-gray\/30:where(.dark,.dark *){color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.dark\:text-bambu-gray\/30:where(.dark,.dark *){color:color-mix(in oklab,var(--color-bambu-gray)30%,transparent)}}.dark\:text-bambu-gray\/50:where(.dark,.dark *){color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.dark\:text-bambu-gray\/50:where(.dark,.dark *){color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.dark\:text-bambu-green:where(.dark,.dark *),.dark\:text-bambu-green\/60:where(.dark,.dark *){color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.dark\:text-bambu-green\/60:where(.dark,.dark *){color:color-mix(in oklab,var(--color-bambu-green)60%,transparent)}}.dark\:text-blue-200:where(.dark,.dark *){color:var(--color-blue-200)}.dark\:text-blue-200\/80:where(.dark,.dark *){color:#bedbffcc}@supports (color:color-mix(in lab,red,red)){.dark\:text-blue-200\/80:where(.dark,.dark *){color:color-mix(in oklab,var(--color-blue-200)80%,transparent)}}.dark\:text-blue-300:where(.dark,.dark *){color:var(--color-blue-300)}.dark\:text-blue-300\/60:where(.dark,.dark *){color:#90c5ff99}@supports (color:color-mix(in lab,red,red)){.dark\:text-blue-300\/60:where(.dark,.dark *){color:color-mix(in oklab,var(--color-blue-300)60%,transparent)}}.dark\:text-blue-400:where(.dark,.dark *){color:var(--color-blue-400)}.dark\:text-orange-200:where(.dark,.dark *){color:var(--color-orange-200)}.dark\:text-orange-400:where(.dark,.dark *){color:var(--color-orange-400)}.dark\:text-red-400:where(.dark,.dark *){color:var(--color-red-400)}.dark\:text-red-400\/70:where(.dark,.dark *){color:#ff6568b3}@supports (color:color-mix(in lab,red,red)){.dark\:text-red-400\/70:where(.dark,.dark *){color:color-mix(in oklab,var(--color-red-400)70%,transparent)}}.dark\:text-white:where(.dark,.dark *){color:var(--color-white)}.dark\:text-yellow-200:where(.dark,.dark *){color:var(--color-yellow-200)}.dark\:text-yellow-200\/70:where(.dark,.dark *){color:#fff085b3}@supports (color:color-mix(in lab,red,red)){.dark\:text-yellow-200\/70:where(.dark,.dark *){color:color-mix(in oklab,var(--color-yellow-200)70%,transparent)}}@media(hover:hover){.dark\:hover\:bg-bambu-dark-tertiary:where(.dark,.dark *):hover{background-color:var(--color-bambu-dark-tertiary)}.dark\:hover\:bg-bambu-dark\/50:where(.dark,.dark *):hover{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-bambu-dark\/50:where(.dark,.dark *):hover{background-color:color-mix(in oklab,var(--color-bambu-dark)50%,transparent)}}.dark\:hover\:bg-red-500\/30:where(.dark,.dark *):hover{background-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-red-500\/30:where(.dark,.dark *):hover{background-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.dark\:hover\:text-white:where(.dark,.dark *):hover{color:var(--color-white)}}.\[\&\:\:-webkit-slider-thumb\]\:h-3::-webkit-slider-thumb{height:calc(var(--spacing)*3)}.\[\&\:\:-webkit-slider-thumb\]\:w-3::-webkit-slider-thumb{width:calc(var(--spacing)*3)}.\[\&\:\:-webkit-slider-thumb\]\:cursor-pointer::-webkit-slider-thumb{cursor:pointer}.\[\&\:\:-webkit-slider-thumb\]\:appearance-none::-webkit-slider-thumb{appearance:none}.\[\&\:\:-webkit-slider-thumb\]\:rounded-full::-webkit-slider-thumb{border-radius:3.40282e38px}.\[\&\:\:-webkit-slider-thumb\]\:bg-bambu-green::-webkit-slider-thumb{background-color:var(--color-bambu-green)}}:root{--accent:#00ae42;--accent-light:#00c64d;--accent-dark:#009438;--status-ok:#22c55e;--status-error:#ef4444;--status-warning:#f59e0b;--bg-primary:#f5f5f5;--bg-secondary:#fff;--bg-tertiary:#e5e5e5;--text-primary:#1a1a1a;--text-secondary:#4a4a4a;--text-muted:#6b6b6b;--text-tertiary:gray;--border-color:#d4d4d4;--card-shadow:0 2px 8px #00000014;--glow-color:transparent;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:Inter,system-ui,sans-serif;font-weight:400;line-height:1.5}.dark{--bg-primary:#1a1a1a;--bg-secondary:#2d2d2d;--bg-tertiary:#3d3d3d;--text-primary:#fff;--text-secondary:#a0a0a0;--text-muted:gray;--text-tertiary:#4a4a4a;--border-color:#3d3d3d;--card-shadow:0 4px 16px #0006}.bg-warm{--bg-primary:#faf8f5;--bg-secondary:#fffefa;--bg-tertiary:#e8e4dd;--text-primary:#2d2a26;--text-secondary:#5c5750;--text-muted:#7a756c;--text-tertiary:#9a9590;--border-color:#d8d4cc}.bg-cool{--bg-primary:#f0f4f8;--bg-secondary:#fff;--bg-tertiary:#dce4ec;--text-primary:#1a2530;--text-secondary:#4a5568;--text-muted:#6b7a8a;--text-tertiary:#8a9aaa;--border-color:#c8d4e0}.dark.bg-neutral{--bg-primary:#1a1a1a;--bg-secondary:#2d2d2d;--bg-tertiary:#3d3d3d;--text-primary:#fff;--text-secondary:#a0a0a0;--text-muted:gray;--text-tertiary:#4a4a4a;--border-color:#3d3d3d}.dark.bg-warm{--bg-primary:#1c1a18;--bg-secondary:#2e2a26;--bg-tertiary:#3e3a36;--text-primary:#f5f0ea;--text-secondary:#b0a898;--text-muted:#8a8278;--text-tertiary:#5a5248;--border-color:#3e3a36}.dark.bg-cool{--bg-primary:#181c20;--bg-secondary:#262c32;--bg-tertiary:#363e46;--text-primary:#f0f4f8;--text-secondary:#98a8b8;--text-muted:#788898;--text-tertiary:#4a5a6a;--border-color:#363e46}.dark.bg-oled{--bg-primary:#000;--bg-secondary:#141414;--bg-tertiary:#1f1f1f;--text-primary:#fff;--text-secondary:#a0a0a0;--text-muted:#707070;--text-tertiary:#404040;--border-color:#2a2a2a}.dark.bg-slate{--bg-primary:#0f172a;--bg-secondary:#1e293b;--bg-tertiary:#334155;--text-primary:#f1f5f9;--text-secondary:#94a3b8;--text-muted:#64748b;--text-tertiary:#475569;--border-color:#334155}.dark.bg-forest{--bg-primary:#121a16;--bg-secondary:#1c2a22;--bg-tertiary:#2a3d30;--text-primary:#e8f5ec;--text-secondary:#8aa894;--text-muted:#6a8874;--text-tertiary:#4a6854;--border-color:#2a3d30}.style-glow{--card-shadow:0 2px 8px #00000014,0 0 25px var(--accent)}@supports (color:color-mix(in lab,red,red)){.style-glow{--card-shadow:0 2px 8px #00000014,0 0 25px color-mix(in srgb,var(--accent)12%,transparent)}}.dark.style-glow{--card-shadow:0 4px 20px #00000080,0 0 40px var(--accent)}@supports (color:color-mix(in lab,red,red)){.dark.style-glow{--card-shadow:0 4px 20px #00000080,0 0 40px color-mix(in srgb,var(--accent)15%,transparent)}}.style-vibrant{--card-shadow:0 8px 30px #00000026,0 2px 8px #0000001a}.dark.style-vibrant{--card-shadow:0 10px 40px #0009,0 4px 12px #0006}.accent-green{--accent:#00ae42;--accent-light:#00c64d;--accent-dark:#009438}.accent-teal{--accent:#14b8a6;--accent-light:#2dd4bf;--accent-dark:#0d9488}.accent-blue{--accent:#3b82f6;--accent-light:#60a5fa;--accent-dark:#2563eb}.accent-orange{--accent:#f97316;--accent-light:#fb923c;--accent-dark:#ea580c}.accent-purple{--accent:#8b5cf6;--accent-light:#a78bfa;--accent-dark:#7c3aed}.accent-red{--accent:#ef4444;--accent-light:#f87171;--accent-dark:#dc2626}body{background-color:var(--bg-primary);color:var(--text-primary);min-height:100vh;margin:0;transition:background-color .2s,color .2s}#root{min-height:100vh}.text-white{color:var(--text-primary)}.bg-bambu-dark,.bg-bambu-dark-secondary,.bg-bambu-dark-tertiary,.border-bambu-dark-tertiary{transition:background-color .2s,border-color .2s}@keyframes slide-in{0%{opacity:0;transform:translate(100%)}to{opacity:1;transform:translate(0)}}.animate-slide-in{animation:.2s ease-out slide-in}.icon-theme{opacity:.5}.dark .icon-theme{filter:invert();opacity:.4}.icon-green{filter:invert(48%)sepia(89%)saturate(459%)hue-rotate(93deg)brightness(95%)contrast(92%);opacity:1}.icon-heating{filter:invert(50%)sepia()saturate(1000%)hue-rotate(360deg)brightness()contrast();opacity:1}.dark .jogpad-theme{filter:brightness(.35)contrast(1.2)}.ams-empty-slot{background:repeating-linear-gradient(45deg,#444,#444 2px,#222 2px 4px)}.dark .ams-empty-slot{background:repeating-linear-gradient(45deg,#555,#555 2px,#333 2px 4px)}.touch-manipulation{touch-action:manipulation}.safe-area-bottom{padding-bottom:env(safe-area-inset-bottom,0)}.safe-area-top{padding-top:env(safe-area-inset-top,0)}.scrollbar-hide{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-hide::-webkit-scrollbar{display:none}@keyframes slide-in-left{0%{transform:translate(-100%)}to{transform:translate(0)}}.animate-slide-in-left{animation:.3s ease-out slide-in-left}.card-shadow{box-shadow:var(--card-shadow)}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:""}}} diff --git a/static/assets/index-CeGzUNH5.js b/static/assets/index-BvTstZiS.js similarity index 89% rename from static/assets/index-CeGzUNH5.js rename to static/assets/index-BvTstZiS.js index f2237663a..f5d080057 100644 --- a/static/assets/index-CeGzUNH5.js +++ b/static/assets/index-BvTstZiS.js @@ -5,16 +5,16 @@ function kae(t,e){for(var n=0;nP||Ie[M]!==it[P]){var yt=` `+Ie[M].replace(" at new "," at ");return h.displayName&&yt.includes("")&&(yt=yt.replace("",h.displayName)),yt}while(1<=M&&0<=P);break}}}finally{$=!1,Error.prepareStackTrace=_}return(_=h?h.displayName||h.name:"")?V(_):""}function U(h,g){switch(h.tag){case 26:case 27:case 5:return V(h.type);case 16:return V("Lazy");case 13:return h.child!==g&&g!==null?V("Suspense Fallback"):V("Suspense");case 19:return V("SuspenseList");case 0:case 15:return X(h.type,!1);case 11:return X(h.type.render,!1);case 1:return X(h.type,!0);case 31:return V("Activity");default:return""}}function B(h){try{var g="",_=null;do g+=U(h,_),_=h,h=h.return;while(h);return g}catch(M){return` Error generating stack: `+M.message+` -`+M.stack}}var oe=Object.prototype.hasOwnProperty,Te=t.unstable_scheduleCallback,je=t.unstable_cancelCallback,Ce=t.unstable_shouldYield,H=t.unstable_requestPaint,D=t.unstable_now,Z=t.unstable_getCurrentPriorityLevel,xe=t.unstable_ImmediatePriority,Ne=t.unstable_UserBlockingPriority,ve=t.unstable_NormalPriority,$e=t.unstable_LowPriority,Le=t.unstable_IdlePriority,qe=t.log,Ke=t.unstable_setDisableYieldValue,Ye=null,ie=null;function te(h){if(typeof qe=="function"&&Ke(h),ie&&typeof ie.setStrictMode=="function")try{ie.setStrictMode(Ye,h)}catch{}}var Se=Math.clz32?Math.clz32:ne,ze=Math.log,nt=Math.LN2;function ne(h){return h>>>=0,h===0?32:31-(ze(h)/nt|0)|0}var Pe=256,be=262144,Oe=4194304;function Ue(h){var g=h&42;if(g!==0)return g;switch(h&-h){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return h&261888;case 262144:case 524288:case 1048576:case 2097152:return h&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return h&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return h}}function Ae(h,g,_){var M=h.pendingLanes;if(M===0)return 0;var P=0,I=h.suspendedLanes,J=h.pingedLanes;h=h.warmLanes;var ge=M&134217727;return ge!==0?(M=ge&~I,M!==0?P=Ue(M):(J&=ge,J!==0?P=Ue(J):_||(_=ge&~h,_!==0&&(P=Ue(_))))):(ge=M&~I,ge!==0?P=Ue(ge):J!==0?P=Ue(J):_||(_=M&~h,_!==0&&(P=Ue(_)))),P===0?0:g!==0&&g!==P&&(g&I)===0&&(I=P&-P,_=g&-g,I>=_||I===32&&(_&4194048)!==0)?g:P}function Je(h,g){return(h.pendingLanes&~(h.suspendedLanes&~h.pingedLanes)&g)===0}function gt(h,g){switch(h){case 1:case 2:case 4:case 8:case 64:return g+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return g+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Pt(){var h=Oe;return Oe<<=1,(Oe&62914560)===0&&(Oe=4194304),h}function Ot(h){for(var g=[],_=0;31>_;_++)g.push(h);return g}function cn(h,g){h.pendingLanes|=g,g!==268435456&&(h.suspendedLanes=0,h.pingedLanes=0,h.warmLanes=0)}function It(h,g,_,M,P,I){var J=h.pendingLanes;h.pendingLanes=_,h.suspendedLanes=0,h.pingedLanes=0,h.warmLanes=0,h.expiredLanes&=_,h.entangledLanes&=_,h.errorRecoveryDisabledLanes&=_,h.shellSuspendCounter=0;var ge=h.entanglements,Ie=h.expirationTimes,it=h.hiddenUpdates;for(_=J&~_;0<_;){var yt=31-Se(_),_t=1<"u")return null;try{return h.activeElement||h.body}catch{return h.body}}var Yt=/[\n"\\]/g;function rn(h){return h.replace(Yt,function(g){return"\\"+g.charCodeAt(0).toString(16)+" "})}function sr(h,g,_,M,P,I,J,ge){h.name="",J!=null&&typeof J!="function"&&typeof J!="symbol"&&typeof J!="boolean"?h.type=J:h.removeAttribute("type"),g!=null?J==="number"?(g===0&&h.value===""||h.value!=g)&&(h.value=""+ye(g)):h.value!==""+ye(g)&&(h.value=""+ye(g)):J!=="submit"&&J!=="reset"||h.removeAttribute("value"),g!=null?Wt(h,J,ye(g)):_!=null?Wt(h,J,ye(_)):M!=null&&h.removeAttribute("value"),P==null&&I!=null&&(h.defaultChecked=!!I),P!=null&&(h.checked=P&&typeof P!="function"&&typeof P!="symbol"),ge!=null&&typeof ge!="function"&&typeof ge!="symbol"&&typeof ge!="boolean"?h.name=""+ye(ge):h.removeAttribute("name")}function kn(h,g,_,M,P,I,J,ge){if(I!=null&&typeof I!="function"&&typeof I!="symbol"&&typeof I!="boolean"&&(h.type=I),g!=null||_!=null){if(!(I!=="submit"&&I!=="reset"||g!=null)){Mt(h);return}_=_!=null?""+ye(_):"",g=g!=null?""+ye(g):_,ge||g===h.value||(h.value=g),h.defaultValue=g}M=M??P,M=typeof M!="function"&&typeof M!="symbol"&&!!M,h.checked=ge?h.checked:!!M,h.defaultChecked=!!M,J!=null&&typeof J!="function"&&typeof J!="symbol"&&typeof J!="boolean"&&(h.name=J),Mt(h)}function Wt(h,g,_){g==="number"&&Xt(h.ownerDocument)===h||h.defaultValue===""+_||(h.defaultValue=""+_)}function en(h,g,_,M){if(h=h.options,g){g={};for(var P=0;P<_.length;P++)g["$"+_[P]]=!0;for(_=0;_"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),_M=!1;if(rc)try{var lx={};Object.defineProperty(lx,"passive",{get:function(){_M=!0}}),window.addEventListener("test",lx,lx),window.removeEventListener("test",lx,lx)}catch{_M=!1}var wu=null,wM=null,Gy=null;function GL(){if(Gy)return Gy;var h,g=wM,_=g.length,M,P="value"in wu?wu.value:wu.textContent,I=P.length;for(h=0;h<_&&g[h]===P[h];h++);var J=_-h;for(M=1;M<=J&&g[_-M]===P[I-M];M++);return Gy=P.slice(h,1=dx),QL=" ",ZL=!1;function JL(h,g){switch(h){case"keyup":return Zre.indexOf(g.keyCode)!==-1;case"keydown":return g.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function eI(h){return h=h.detail,typeof h=="object"&&"data"in h?h.data:null}var lm=!1;function eie(h,g){switch(h){case"compositionend":return eI(g);case"keypress":return g.which!==32?null:(ZL=!0,QL);case"textInput":return h=g.data,h===QL&&ZL?null:h;default:return null}}function tie(h,g){if(lm)return h==="compositionend"||!TM&&JL(h,g)?(h=GL(),Gy=wM=wu=null,lm=!1,h):null;switch(h){case"paste":return null;case"keypress":if(!(g.ctrlKey||g.altKey||g.metaKey)||g.ctrlKey&&g.altKey){if(g.char&&1=g)return{node:_,offset:g-h};h=M}e:{for(;_;){if(_.nextSibling){_=_.nextSibling;break e}_=_.parentNode}_=void 0}_=lI(_)}}function uI(h,g){return h&&g?h===g?!0:h&&h.nodeType===3?!1:g&&g.nodeType===3?uI(h,g.parentNode):"contains"in h?h.contains(g):h.compareDocumentPosition?!!(h.compareDocumentPosition(g)&16):!1:!1}function dI(h){h=h!=null&&h.ownerDocument!=null&&h.ownerDocument.defaultView!=null?h.ownerDocument.defaultView:window;for(var g=Xt(h.document);g instanceof h.HTMLIFrameElement;){try{var _=typeof g.contentWindow.location.href=="string"}catch{_=!1}if(_)h=g.contentWindow;else break;g=Xt(h.document)}return g}function kM(h){var g=h&&h.nodeName&&h.nodeName.toLowerCase();return g&&(g==="input"&&(h.type==="text"||h.type==="search"||h.type==="tel"||h.type==="url"||h.type==="password")||g==="textarea"||h.contentEditable==="true")}var cie=rc&&"documentMode"in document&&11>=document.documentMode,cm=null,jM=null,px=null,PM=!1;function hI(h,g,_){var M=_.window===_?_.document:_.nodeType===9?_:_.ownerDocument;PM||cm==null||cm!==Xt(M)||(M=cm,"selectionStart"in M&&kM(M)?M={start:M.selectionStart,end:M.selectionEnd}:(M=(M.ownerDocument&&M.ownerDocument.defaultView||window).getSelection(),M={anchorNode:M.anchorNode,anchorOffset:M.anchorOffset,focusNode:M.focusNode,focusOffset:M.focusOffset}),px&&mx(px,M)||(px=M,M=Fv(jM,"onSelect"),0>=J,P-=J,gl=1<<32-Se(g)+P|_<vn?(In=qt,qt=null):In=qt.sibling;var Wn=st(Ze,qt,tt[vn],vt);if(Wn===null){qt===null&&(qt=In);break}h&&qt&&Wn.alternate===null&&g(Ze,qt),Ge=I(Wn,Ge,vn),Gn===null?Zt=Wn:Gn.sibling=Wn,Gn=Wn,qt=In}if(vn===tt.length)return _(Ze,qt),Un&&ac(Ze,vn),Zt;if(qt===null){for(;vnvn?(In=qt,qt=null):In=qt.sibling;var Vu=st(Ze,qt,Wn.value,vt);if(Vu===null){qt===null&&(qt=In);break}h&&qt&&Vu.alternate===null&&g(Ze,qt),Ge=I(Vu,Ge,vn),Gn===null?Zt=Vu:Gn.sibling=Vu,Gn=Vu,qt=In}if(Wn.done)return _(Ze,qt),Un&&ac(Ze,vn),Zt;if(qt===null){for(;!Wn.done;vn++,Wn=tt.next())Wn=_t(Ze,Wn.value,vt),Wn!==null&&(Ge=I(Wn,Ge,vn),Gn===null?Zt=Wn:Gn.sibling=Wn,Gn=Wn);return Un&&ac(Ze,vn),Zt}for(qt=M(qt);!Wn.done;vn++,Wn=tt.next())Wn=ft(qt,Ze,vn,Wn.value,vt),Wn!==null&&(h&&Wn.alternate!==null&&qt.delete(Wn.key===null?vn:Wn.key),Ge=I(Wn,Ge,vn),Gn===null?Zt=Wn:Gn.sibling=Wn,Gn=Wn);return h&&qt.forEach(function(Cae){return g(Ze,Cae)}),Un&&ac(Ze,vn),Zt}function ur(Ze,Ge,tt,vt){if(typeof tt=="object"&&tt!==null&&tt.type===y&&tt.key===null&&(tt=tt.props.children),typeof tt=="object"&&tt!==null){switch(tt.$$typeof){case p:e:{for(var Zt=tt.key;Ge!==null;){if(Ge.key===Zt){if(Zt=tt.type,Zt===y){if(Ge.tag===7){_(Ze,Ge.sibling),vt=P(Ge,tt.props.children),vt.return=Ze,Ze=vt;break e}}else if(Ge.elementType===Zt||typeof Zt=="object"&&Zt!==null&&Zt.$$typeof===O&&_h(Zt)===Ge.type){_(Ze,Ge.sibling),vt=P(Ge,tt.props),_x(vt,tt),vt.return=Ze,Ze=vt;break e}_(Ze,Ge);break}else g(Ze,Ge);Ge=Ge.sibling}tt.type===y?(vt=gh(tt.props.children,Ze.mode,vt,tt.key),vt.return=Ze,Ze=vt):(vt=tv(tt.type,tt.key,tt.props,null,Ze.mode,vt),_x(vt,tt),vt.return=Ze,Ze=vt)}return J(Ze);case x:e:{for(Zt=tt.key;Ge!==null;){if(Ge.key===Zt)if(Ge.tag===4&&Ge.stateNode.containerInfo===tt.containerInfo&&Ge.stateNode.implementation===tt.implementation){_(Ze,Ge.sibling),vt=P(Ge,tt.children||[]),vt.return=Ze,Ze=vt;break e}else{_(Ze,Ge);break}else g(Ze,Ge);Ge=Ge.sibling}vt=UM(tt,Ze.mode,vt),vt.return=Ze,Ze=vt}return J(Ze);case O:return tt=_h(tt),ur(Ze,Ge,tt,vt)}if(W(tt))return Vt(Ze,Ge,tt,vt);if(L(tt)){if(Zt=L(tt),typeof Zt!="function")throw Error(r(150));return tt=Zt.call(tt),an(Ze,Ge,tt,vt)}if(typeof tt.then=="function")return ur(Ze,Ge,lv(tt),vt);if(tt.$$typeof===S)return ur(Ze,Ge,iv(Ze,tt),vt);cv(Ze,tt)}return typeof tt=="string"&&tt!==""||typeof tt=="number"||typeof tt=="bigint"?(tt=""+tt,Ge!==null&&Ge.tag===6?(_(Ze,Ge.sibling),vt=P(Ge,tt),vt.return=Ze,Ze=vt):(_(Ze,Ge),vt=FM(tt,Ze.mode,vt),vt.return=Ze,Ze=vt),J(Ze)):_(Ze,Ge)}return function(Ze,Ge,tt,vt){try{vx=0;var Zt=ur(Ze,Ge,tt,vt);return vm=null,Zt}catch(qt){if(qt===ym||qt===sv)throw qt;var Gn=As(29,qt,null,Ze.mode);return Gn.lanes=vt,Gn.return=Ze,Gn}finally{}}}var Sh=OI(!0),LI=OI(!1),Tu=!1;function QM(h){h.updateQueue={baseState:h.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function ZM(h,g){h=h.updateQueue,g.updateQueue===h&&(g.updateQueue={baseState:h.baseState,firstBaseUpdate:h.firstBaseUpdate,lastBaseUpdate:h.lastBaseUpdate,shared:h.shared,callbacks:null})}function Au(h){return{lane:h,tag:0,payload:null,callback:null,next:null}}function Cu(h,g,_){var M=h.updateQueue;if(M===null)return null;if(M=M.shared,(Yn&2)!==0){var P=M.pending;return P===null?g.next=g:(g.next=P.next,P.next=g),M.pending=g,g=ev(h),yI(h,null,_),g}return Jy(h,M,g,_),ev(h)}function wx(h,g,_){if(g=g.updateQueue,g!==null&&(g=g.shared,(_&4194048)!==0)){var M=g.lanes;M&=h.pendingLanes,_|=M,g.lanes=_,bt(h,_)}}function JM(h,g){var _=h.updateQueue,M=h.alternate;if(M!==null&&(M=M.updateQueue,_===M)){var P=null,I=null;if(_=_.firstBaseUpdate,_!==null){do{var J={lane:_.lane,tag:_.tag,payload:_.payload,callback:null,next:null};I===null?P=I=J:I=I.next=J,_=_.next}while(_!==null);I===null?P=I=g:I=I.next=g}else P=I=g;_={baseState:M.baseState,firstBaseUpdate:P,lastBaseUpdate:I,shared:M.shared,callbacks:M.callbacks},h.updateQueue=_;return}h=_.lastBaseUpdate,h===null?_.firstBaseUpdate=g:h.next=g,_.lastBaseUpdate=g}var eE=!1;function Sx(){if(eE){var h=bm;if(h!==null)throw h}}function Nx(h,g,_,M){eE=!1;var P=h.updateQueue;Tu=!1;var I=P.firstBaseUpdate,J=P.lastBaseUpdate,ge=P.shared.pending;if(ge!==null){P.shared.pending=null;var Ie=ge,it=Ie.next;Ie.next=null,J===null?I=it:J.next=it,J=Ie;var yt=h.alternate;yt!==null&&(yt=yt.updateQueue,ge=yt.lastBaseUpdate,ge!==J&&(ge===null?yt.firstBaseUpdate=it:ge.next=it,yt.lastBaseUpdate=Ie))}if(I!==null){var _t=P.baseState;J=0,yt=it=Ie=null,ge=I;do{var st=ge.lane&-536870913,ft=st!==ge.lane;if(ft?(Ln&st)===st:(M&st)===st){st!==0&&st===xm&&(eE=!0),yt!==null&&(yt=yt.next={lane:0,tag:ge.tag,payload:ge.payload,callback:null,next:null});e:{var Vt=h,an=ge;st=g;var ur=_;switch(an.tag){case 1:if(Vt=an.payload,typeof Vt=="function"){_t=Vt.call(ur,_t,st);break e}_t=Vt;break e;case 3:Vt.flags=Vt.flags&-65537|128;case 0:if(Vt=an.payload,st=typeof Vt=="function"?Vt.call(ur,_t,st):Vt,st==null)break e;_t=f({},_t,st);break e;case 2:Tu=!0}}st=ge.callback,st!==null&&(h.flags|=64,ft&&(h.flags|=8192),ft=P.callbacks,ft===null?P.callbacks=[st]:ft.push(st))}else ft={lane:st,tag:ge.tag,payload:ge.payload,callback:ge.callback,next:null},yt===null?(it=yt=ft,Ie=_t):yt=yt.next=ft,J|=st;if(ge=ge.next,ge===null){if(ge=P.shared.pending,ge===null)break;ft=ge,ge=ft.next,ft.next=null,P.lastBaseUpdate=ft,P.shared.pending=null}}while(!0);yt===null&&(Ie=_t),P.baseState=Ie,P.firstBaseUpdate=it,P.lastBaseUpdate=yt,I===null&&(P.shared.lanes=0),Du|=J,h.lanes=J,h.memoizedState=_t}}function II(h,g){if(typeof h!="function")throw Error(r(191,h));h.call(g)}function FI(h,g){var _=h.callbacks;if(_!==null)for(h.callbacks=null,h=0;h<_.length;h++)II(_[h],g)}var _m=z(null),uv=z(0);function UI(h,g){h=gc,ae(uv,h),ae(_m,g),gc=h|g.baseLanes}function tE(){ae(uv,gc),ae(_m,_m.current)}function nE(){gc=uv.current,G(_m),G(uv)}var Cs=z(null),ao=null;function ku(h){var g=h.alternate;ae(oi,oi.current&1),ae(Cs,h),ao===null&&(g===null||_m.current!==null||g.memoizedState!==null)&&(ao=h)}function rE(h){ae(oi,oi.current),ae(Cs,h),ao===null&&(ao=h)}function zI(h){h.tag===22?(ae(oi,oi.current),ae(Cs,h),ao===null&&(ao=h)):ju()}function ju(){ae(oi,oi.current),ae(Cs,Cs.current)}function ks(h){G(Cs),ao===h&&(ao=null),G(oi)}var oi=z(0);function dv(h){for(var g=h;g!==null;){if(g.tag===13){var _=g.memoizedState;if(_!==null&&(_=_.dehydrated,_===null||cT(_)||uT(_)))return g}else if(g.tag===19&&(g.memoizedProps.revealOrder==="forwards"||g.memoizedProps.revealOrder==="backwards"||g.memoizedProps.revealOrder==="unstable_legacy-backwards"||g.memoizedProps.revealOrder==="together")){if((g.flags&128)!==0)return g}else if(g.child!==null){g.child.return=g,g=g.child;continue}if(g===h)break;for(;g.sibling===null;){if(g.return===null||g.return===h)return null;g=g.return}g.sibling.return=g.return,g=g.sibling}return null}var lc=0,bn=null,lr=null,mi=null,hv=!1,wm=!1,Nh=!1,fv=0,Mx=0,Sm=null,yie=0;function Yr(){throw Error(r(321))}function iE(h,g){if(g===null)return!1;for(var _=0;_I?I:8;var J=Y.T,ge={};Y.T=ge,yE(h,!1,g,_);try{var Ie=P(),it=Y.S;if(it!==null&&it(ge,Ie),Ie!==null&&typeof Ie=="object"&&typeof Ie.then=="function"){var yt=bie(Ie,M);Tx(h,g,yt,Rs(h))}else Tx(h,g,M,Rs(h))}catch(_t){Tx(h,g,{then:function(){},status:"rejected",reason:_t},Rs())}finally{q.p=I,J!==null&&ge.types!==null&&(J.types=ge.types),Y.T=J}}function Nie(){}function xE(h,g,_,M){if(h.tag!==5)throw Error(r(476));var P=g5(h).queue;p5(h,P,g,Q,_===null?Nie:function(){return x5(h),_(M)})}function g5(h){var g=h.memoizedState;if(g!==null)return g;g={memoizedState:Q,baseState:Q,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:cc,lastRenderedState:Q},next:null};var _={};return g.next={memoizedState:_,baseState:_,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:cc,lastRenderedState:_},next:null},h.memoizedState=g,h=h.alternate,h!==null&&(h.memoizedState=g),g}function x5(h){var g=g5(h);g.next===null&&(g=h.alternate.memoizedState),Tx(h,g.next.queue,{},Rs())}function bE(){return la(Vx)}function b5(){return li().memoizedState}function y5(){return li().memoizedState}function Mie(h){for(var g=h.return;g!==null;){switch(g.tag){case 24:case 3:var _=Rs();h=Au(_);var M=Cu(g,h,_);M!==null&&(cs(M,g,_),wx(M,g,_)),g={cache:qM()},h.payload=g;return}g=g.return}}function Eie(h,g,_){var M=Rs();_={lane:M,revertLane:0,gesture:null,action:_,hasEagerState:!1,eagerState:null,next:null},yv(h)?_5(g,_):(_=LM(h,g,_,M),_!==null&&(cs(_,h,M),w5(_,g,M)))}function v5(h,g,_){var M=Rs();Tx(h,g,_,M)}function Tx(h,g,_,M){var P={lane:M,revertLane:0,gesture:null,action:_,hasEagerState:!1,eagerState:null,next:null};if(yv(h))_5(g,P);else{var I=h.alternate;if(h.lanes===0&&(I===null||I.lanes===0)&&(I=g.lastRenderedReducer,I!==null))try{var J=g.lastRenderedState,ge=I(J,_);if(P.hasEagerState=!0,P.eagerState=ge,Ts(ge,J))return Jy(h,g,P,0),yr===null&&Zy(),!1}catch{}finally{}if(_=LM(h,g,P,M),_!==null)return cs(_,h,M),w5(_,g,M),!0}return!1}function yE(h,g,_,M){if(M={lane:2,revertLane:QE(),gesture:null,action:M,hasEagerState:!1,eagerState:null,next:null},yv(h)){if(g)throw Error(r(479))}else g=LM(h,_,M,2),g!==null&&cs(g,h,2)}function yv(h){var g=h.alternate;return h===bn||g!==null&&g===bn}function _5(h,g){wm=hv=!0;var _=h.pending;_===null?g.next=g:(g.next=_.next,_.next=g),h.pending=g}function w5(h,g,_){if((_&4194048)!==0){var M=g.lanes;M&=h.pendingLanes,_|=M,g.lanes=_,bt(h,_)}}var Ax={readContext:la,use:pv,useCallback:Yr,useContext:Yr,useEffect:Yr,useImperativeHandle:Yr,useLayoutEffect:Yr,useInsertionEffect:Yr,useMemo:Yr,useReducer:Yr,useRef:Yr,useState:Yr,useDebugValue:Yr,useDeferredValue:Yr,useTransition:Yr,useSyncExternalStore:Yr,useId:Yr,useHostTransitionStatus:Yr,useFormState:Yr,useActionState:Yr,useOptimistic:Yr,useMemoCache:Yr,useCacheRefresh:Yr};Ax.useEffectEvent=Yr;var S5={readContext:la,use:pv,useCallback:function(h,g){return za().memoizedState=[h,g===void 0?null:g],h},useContext:la,useEffect:s5,useImperativeHandle:function(h,g,_){_=_!=null?_.concat([h]):null,xv(4194308,4,u5.bind(null,g,h),_)},useLayoutEffect:function(h,g){return xv(4194308,4,h,g)},useInsertionEffect:function(h,g){xv(4,2,h,g)},useMemo:function(h,g){var _=za();g=g===void 0?null:g;var M=h();if(Nh){te(!0);try{h()}finally{te(!1)}}return _.memoizedState=[M,g],M},useReducer:function(h,g,_){var M=za();if(_!==void 0){var P=_(g);if(Nh){te(!0);try{_(g)}finally{te(!1)}}}else P=g;return M.memoizedState=M.baseState=P,h={pending:null,lanes:0,dispatch:null,lastRenderedReducer:h,lastRenderedState:P},M.queue=h,h=h.dispatch=Eie.bind(null,bn,h),[M.memoizedState,h]},useRef:function(h){var g=za();return h={current:h},g.memoizedState=h},useState:function(h){h=hE(h);var g=h.queue,_=v5.bind(null,bn,g);return g.dispatch=_,[h.memoizedState,_]},useDebugValue:pE,useDeferredValue:function(h,g){var _=za();return gE(_,h,g)},useTransition:function(){var h=hE(!1);return h=p5.bind(null,bn,h.queue,!0,!1),za().memoizedState=h,[!1,h]},useSyncExternalStore:function(h,g,_){var M=bn,P=za();if(Un){if(_===void 0)throw Error(r(407));_=_()}else{if(_=g(),yr===null)throw Error(r(349));(Ln&127)!==0||VI(M,g,_)}P.memoizedState=_;var I={value:_,getSnapshot:g};return P.queue=I,s5(WI.bind(null,M,I,h),[h]),M.flags|=2048,Nm(9,{destroy:void 0},GI.bind(null,M,I,_,g),null),_},useId:function(){var h=za(),g=yr.identifierPrefix;if(Un){var _=xl,M=gl;_=(M&~(1<<32-Se(M)-1)).toString(32)+_,g="_"+g+"R_"+_,_=fv++,0<_&&(g+="H"+_.toString(32)),g+="_"}else _=yie++,g="_"+g+"r_"+_.toString(32)+"_";return h.memoizedState=g},useHostTransitionStatus:bE,useFormState:t5,useActionState:t5,useOptimistic:function(h){var g=za();g.memoizedState=g.baseState=h;var _={pending:null,lanes:0,dispatch:null,lastRenderedReducer:null,lastRenderedState:null};return g.queue=_,g=yE.bind(null,bn,!0,_),_.dispatch=g,[h,g]},useMemoCache:cE,useCacheRefresh:function(){return za().memoizedState=Mie.bind(null,bn)},useEffectEvent:function(h){var g=za(),_={impl:h};return g.memoizedState=_,function(){if((Yn&2)!==0)throw Error(r(440));return _.impl.apply(void 0,arguments)}}},vE={readContext:la,use:pv,useCallback:h5,useContext:la,useEffect:mE,useImperativeHandle:d5,useInsertionEffect:l5,useLayoutEffect:c5,useMemo:f5,useReducer:gv,useRef:a5,useState:function(){return gv(cc)},useDebugValue:pE,useDeferredValue:function(h,g){var _=li();return m5(_,lr.memoizedState,h,g)},useTransition:function(){var h=gv(cc)[0],g=li().memoizedState;return[typeof h=="boolean"?h:Ex(h),g]},useSyncExternalStore:HI,useId:b5,useHostTransitionStatus:bE,useFormState:n5,useActionState:n5,useOptimistic:function(h,g){var _=li();return XI(_,lr,h,g)},useMemoCache:cE,useCacheRefresh:y5};vE.useEffectEvent=o5;var N5={readContext:la,use:pv,useCallback:h5,useContext:la,useEffect:mE,useImperativeHandle:d5,useInsertionEffect:l5,useLayoutEffect:c5,useMemo:f5,useReducer:dE,useRef:a5,useState:function(){return dE(cc)},useDebugValue:pE,useDeferredValue:function(h,g){var _=li();return lr===null?gE(_,h,g):m5(_,lr.memoizedState,h,g)},useTransition:function(){var h=dE(cc)[0],g=li().memoizedState;return[typeof h=="boolean"?h:Ex(h),g]},useSyncExternalStore:HI,useId:b5,useHostTransitionStatus:bE,useFormState:i5,useActionState:i5,useOptimistic:function(h,g){var _=li();return lr!==null?XI(_,lr,h,g):(_.baseState=h,[h,_.queue.dispatch])},useMemoCache:cE,useCacheRefresh:y5};N5.useEffectEvent=o5;function _E(h,g,_,M){g=h.memoizedState,_=_(M,g),_=_==null?g:f({},g,_),h.memoizedState=_,h.lanes===0&&(h.updateQueue.baseState=_)}var wE={enqueueSetState:function(h,g,_){h=h._reactInternals;var M=Rs(),P=Au(M);P.payload=g,_!=null&&(P.callback=_),g=Cu(h,P,M),g!==null&&(cs(g,h,M),wx(g,h,M))},enqueueReplaceState:function(h,g,_){h=h._reactInternals;var M=Rs(),P=Au(M);P.tag=1,P.payload=g,_!=null&&(P.callback=_),g=Cu(h,P,M),g!==null&&(cs(g,h,M),wx(g,h,M))},enqueueForceUpdate:function(h,g){h=h._reactInternals;var _=Rs(),M=Au(_);M.tag=2,g!=null&&(M.callback=g),g=Cu(h,M,_),g!==null&&(cs(g,h,_),wx(g,h,_))}};function M5(h,g,_,M,P,I,J){return h=h.stateNode,typeof h.shouldComponentUpdate=="function"?h.shouldComponentUpdate(M,I,J):g.prototype&&g.prototype.isPureReactComponent?!mx(_,M)||!mx(P,I):!0}function E5(h,g,_,M){h=g.state,typeof g.componentWillReceiveProps=="function"&&g.componentWillReceiveProps(_,M),typeof g.UNSAFE_componentWillReceiveProps=="function"&&g.UNSAFE_componentWillReceiveProps(_,M),g.state!==h&&wE.enqueueReplaceState(g,g.state,null)}function Mh(h,g){var _=g;if("ref"in g){_={};for(var M in g)M!=="ref"&&(_[M]=g[M])}if(h=h.defaultProps){_===g&&(_=f({},_));for(var P in h)_[P]===void 0&&(_[P]=h[P])}return _}function T5(h){Qy(h)}function A5(h){console.error(h)}function C5(h){Qy(h)}function vv(h,g){try{var _=h.onUncaughtError;_(g.value,{componentStack:g.stack})}catch(M){setTimeout(function(){throw M})}}function k5(h,g,_){try{var M=h.onCaughtError;M(_.value,{componentStack:_.stack,errorBoundary:g.tag===1?g.stateNode:null})}catch(P){setTimeout(function(){throw P})}}function SE(h,g,_){return _=Au(_),_.tag=3,_.payload={element:null},_.callback=function(){vv(h,g)},_}function j5(h){return h=Au(h),h.tag=3,h}function P5(h,g,_,M){var P=_.type.getDerivedStateFromError;if(typeof P=="function"){var I=M.value;h.payload=function(){return P(I)},h.callback=function(){k5(g,_,M)}}var J=_.stateNode;J!==null&&typeof J.componentDidCatch=="function"&&(h.callback=function(){k5(g,_,M),typeof P!="function"&&(Ou===null?Ou=new Set([this]):Ou.add(this));var ge=M.stack;this.componentDidCatch(M.value,{componentStack:ge!==null?ge:""})})}function Tie(h,g,_,M,P){if(_.flags|=32768,M!==null&&typeof M=="object"&&typeof M.then=="function"){if(g=_.alternate,g!==null&&gm(g,_,P,!0),_=Cs.current,_!==null){switch(_.tag){case 31:case 13:return ao===null?Pv():_.alternate===null&&Qr===0&&(Qr=3),_.flags&=-257,_.flags|=65536,_.lanes=P,M===ov?_.flags|=16384:(g=_.updateQueue,g===null?_.updateQueue=new Set([M]):g.add(M),KE(h,M,P)),!1;case 22:return _.flags|=65536,M===ov?_.flags|=16384:(g=_.updateQueue,g===null?(g={transitions:null,markerInstances:null,retryQueue:new Set([M])},_.updateQueue=g):(_=g.retryQueue,_===null?g.retryQueue=new Set([M]):_.add(M)),KE(h,M,P)),!1}throw Error(r(435,_.tag))}return KE(h,M,P),Pv(),!1}if(Un)return g=Cs.current,g!==null?((g.flags&65536)===0&&(g.flags|=256),g.flags|=65536,g.lanes=P,M!==$M&&(h=Error(r(422),{cause:M}),xx(to(h,_)))):(M!==$M&&(g=Error(r(423),{cause:M}),xx(to(g,_))),h=h.current.alternate,h.flags|=65536,P&=-P,h.lanes|=P,M=to(M,_),P=SE(h.stateNode,M,P),JM(h,P),Qr!==4&&(Qr=2)),!1;var I=Error(r(520),{cause:M});if(I=to(I,_),Lx===null?Lx=[I]:Lx.push(I),Qr!==4&&(Qr=2),g===null)return!0;M=to(M,_),_=g;do{switch(_.tag){case 3:return _.flags|=65536,h=P&-P,_.lanes|=h,h=SE(_.stateNode,M,h),JM(_,h),!1;case 1:if(g=_.type,I=_.stateNode,(_.flags&128)===0&&(typeof g.getDerivedStateFromError=="function"||I!==null&&typeof I.componentDidCatch=="function"&&(Ou===null||!Ou.has(I))))return _.flags|=65536,P&=-P,_.lanes|=P,P=j5(P),P5(P,h,_,M),JM(_,P),!1}_=_.return}while(_!==null);return!1}var NE=Error(r(461)),pi=!1;function ca(h,g,_,M){g.child=h===null?LI(g,null,_,M):Sh(g,h.child,_,M)}function R5(h,g,_,M,P){_=_.render;var I=g.ref;if("ref"in M){var J={};for(var ge in M)ge!=="ref"&&(J[ge]=M[ge])}else J=M;return yh(g),M=aE(h,g,_,J,I,P),ge=sE(),h!==null&&!pi?(oE(h,g,P),uc(h,g,P)):(Un&&ge&&zM(g),g.flags|=1,ca(h,g,M,P),g.child)}function D5(h,g,_,M,P){if(h===null){var I=_.type;return typeof I=="function"&&!IM(I)&&I.defaultProps===void 0&&_.compare===null?(g.tag=15,g.type=I,O5(h,g,I,M,P)):(h=tv(_.type,null,M,g,g.mode,P),h.ref=g.ref,h.return=g,g.child=h)}if(I=h.child,!PE(h,P)){var J=I.memoizedProps;if(_=_.compare,_=_!==null?_:mx,_(J,M)&&h.ref===g.ref)return uc(h,g,P)}return g.flags|=1,h=ic(I,M),h.ref=g.ref,h.return=g,g.child=h}function O5(h,g,_,M,P){if(h!==null){var I=h.memoizedProps;if(mx(I,M)&&h.ref===g.ref)if(pi=!1,g.pendingProps=M=I,PE(h,P))(h.flags&131072)!==0&&(pi=!0);else return g.lanes=h.lanes,uc(h,g,P)}return ME(h,g,_,M,P)}function L5(h,g,_,M){var P=M.children,I=h!==null?h.memoizedState:null;if(h===null&&g.stateNode===null&&(g.stateNode={_visibility:1,_pendingMarkers:null,_retryCache:null,_transitions:null}),M.mode==="hidden"){if((g.flags&128)!==0){if(I=I!==null?I.baseLanes|_:_,h!==null){for(M=g.child=h.child,P=0;M!==null;)P=P|M.lanes|M.childLanes,M=M.sibling;M=P&~I}else M=0,g.child=null;return I5(h,g,I,_,M)}if((_&536870912)!==0)g.memoizedState={baseLanes:0,cachePool:null},h!==null&&av(g,I!==null?I.cachePool:null),I!==null?UI(g,I):tE(),zI(g);else return M=g.lanes=536870912,I5(h,g,I!==null?I.baseLanes|_:_,_,M)}else I!==null?(av(g,I.cachePool),UI(g,I),ju(),g.memoizedState=null):(h!==null&&av(g,null),tE(),ju());return ca(h,g,P,_),g.child}function Cx(h,g){return h!==null&&h.tag===22||g.stateNode!==null||(g.stateNode={_visibility:1,_pendingMarkers:null,_retryCache:null,_transitions:null}),g.sibling}function I5(h,g,_,M,P){var I=XM();return I=I===null?null:{parent:fi._currentValue,pool:I},g.memoizedState={baseLanes:_,cachePool:I},h!==null&&av(g,null),tE(),zI(g),h!==null&&gm(h,g,M,!0),g.childLanes=P,null}function _v(h,g){return g=Sv({mode:g.mode,children:g.children},h.mode),g.ref=h.ref,h.child=g,g.return=h,g}function F5(h,g,_){return Sh(g,h.child,null,_),h=_v(g,g.pendingProps),h.flags|=2,ks(g),g.memoizedState=null,h}function Aie(h,g,_){var M=g.pendingProps,P=(g.flags&128)!==0;if(g.flags&=-129,h===null){if(Un){if(M.mode==="hidden")return h=_v(g,M),g.lanes=536870912,Cx(null,h);if(rE(g),(h=Tr)?(h=YF(h,io),h=h!==null&&h.data==="&"?h:null,h!==null&&(g.memoizedState={dehydrated:h,treeContext:Su!==null?{id:gl,overflow:xl}:null,retryLane:536870912,hydrationErrors:null},_=_I(h),_.return=g,g.child=_,oa=g,Tr=null)):h=null,h===null)throw Mu(g);return g.lanes=536870912,null}return _v(g,M)}var I=h.memoizedState;if(I!==null){var J=I.dehydrated;if(rE(g),P)if(g.flags&256)g.flags&=-257,g=F5(h,g,_);else if(g.memoizedState!==null)g.child=h.child,g.flags|=128,g=null;else throw Error(r(558));else if(pi||gm(h,g,_,!1),P=(_&h.childLanes)!==0,pi||P){if(M=yr,M!==null&&(J=Gt(M,_),J!==0&&J!==I.retryLane))throw I.retryLane=J,ph(h,J),cs(M,h,J),NE;Pv(),g=F5(h,g,_)}else h=I.treeContext,Tr=so(J.nextSibling),oa=g,Un=!0,Nu=null,io=!1,h!==null&&NI(g,h),g=_v(g,M),g.flags|=4096;return g}return h=ic(h.child,{mode:M.mode,children:M.children}),h.ref=g.ref,g.child=h,h.return=g,h}function wv(h,g){var _=g.ref;if(_===null)h!==null&&h.ref!==null&&(g.flags|=4194816);else{if(typeof _!="function"&&typeof _!="object")throw Error(r(284));(h===null||h.ref!==_)&&(g.flags|=4194816)}}function ME(h,g,_,M,P){return yh(g),_=aE(h,g,_,M,void 0,P),M=sE(),h!==null&&!pi?(oE(h,g,P),uc(h,g,P)):(Un&&M&&zM(g),g.flags|=1,ca(h,g,_,P),g.child)}function U5(h,g,_,M,P,I){return yh(g),g.updateQueue=null,_=$I(g,M,_,P),BI(h),M=sE(),h!==null&&!pi?(oE(h,g,I),uc(h,g,I)):(Un&&M&&zM(g),g.flags|=1,ca(h,g,_,I),g.child)}function z5(h,g,_,M,P){if(yh(g),g.stateNode===null){var I=hm,J=_.contextType;typeof J=="object"&&J!==null&&(I=la(J)),I=new _(M,I),g.memoizedState=I.state!==null&&I.state!==void 0?I.state:null,I.updater=wE,g.stateNode=I,I._reactInternals=g,I=g.stateNode,I.props=M,I.state=g.memoizedState,I.refs={},QM(g),J=_.contextType,I.context=typeof J=="object"&&J!==null?la(J):hm,I.state=g.memoizedState,J=_.getDerivedStateFromProps,typeof J=="function"&&(_E(g,_,J,M),I.state=g.memoizedState),typeof _.getDerivedStateFromProps=="function"||typeof I.getSnapshotBeforeUpdate=="function"||typeof I.UNSAFE_componentWillMount!="function"&&typeof I.componentWillMount!="function"||(J=I.state,typeof I.componentWillMount=="function"&&I.componentWillMount(),typeof I.UNSAFE_componentWillMount=="function"&&I.UNSAFE_componentWillMount(),J!==I.state&&wE.enqueueReplaceState(I,I.state,null),Nx(g,M,I,P),Sx(),I.state=g.memoizedState),typeof I.componentDidMount=="function"&&(g.flags|=4194308),M=!0}else if(h===null){I=g.stateNode;var ge=g.memoizedProps,Ie=Mh(_,ge);I.props=Ie;var it=I.context,yt=_.contextType;J=hm,typeof yt=="object"&&yt!==null&&(J=la(yt));var _t=_.getDerivedStateFromProps;yt=typeof _t=="function"||typeof I.getSnapshotBeforeUpdate=="function",ge=g.pendingProps!==ge,yt||typeof I.UNSAFE_componentWillReceiveProps!="function"&&typeof I.componentWillReceiveProps!="function"||(ge||it!==J)&&E5(g,I,M,J),Tu=!1;var st=g.memoizedState;I.state=st,Nx(g,M,I,P),Sx(),it=g.memoizedState,ge||st!==it||Tu?(typeof _t=="function"&&(_E(g,_,_t,M),it=g.memoizedState),(Ie=Tu||M5(g,_,Ie,M,st,it,J))?(yt||typeof I.UNSAFE_componentWillMount!="function"&&typeof I.componentWillMount!="function"||(typeof I.componentWillMount=="function"&&I.componentWillMount(),typeof I.UNSAFE_componentWillMount=="function"&&I.UNSAFE_componentWillMount()),typeof I.componentDidMount=="function"&&(g.flags|=4194308)):(typeof I.componentDidMount=="function"&&(g.flags|=4194308),g.memoizedProps=M,g.memoizedState=it),I.props=M,I.state=it,I.context=J,M=Ie):(typeof I.componentDidMount=="function"&&(g.flags|=4194308),M=!1)}else{I=g.stateNode,ZM(h,g),J=g.memoizedProps,yt=Mh(_,J),I.props=yt,_t=g.pendingProps,st=I.context,it=_.contextType,Ie=hm,typeof it=="object"&&it!==null&&(Ie=la(it)),ge=_.getDerivedStateFromProps,(it=typeof ge=="function"||typeof I.getSnapshotBeforeUpdate=="function")||typeof I.UNSAFE_componentWillReceiveProps!="function"&&typeof I.componentWillReceiveProps!="function"||(J!==_t||st!==Ie)&&E5(g,I,M,Ie),Tu=!1,st=g.memoizedState,I.state=st,Nx(g,M,I,P),Sx();var ft=g.memoizedState;J!==_t||st!==ft||Tu||h!==null&&h.dependencies!==null&&rv(h.dependencies)?(typeof ge=="function"&&(_E(g,_,ge,M),ft=g.memoizedState),(yt=Tu||M5(g,_,yt,M,st,ft,Ie)||h!==null&&h.dependencies!==null&&rv(h.dependencies))?(it||typeof I.UNSAFE_componentWillUpdate!="function"&&typeof I.componentWillUpdate!="function"||(typeof I.componentWillUpdate=="function"&&I.componentWillUpdate(M,ft,Ie),typeof I.UNSAFE_componentWillUpdate=="function"&&I.UNSAFE_componentWillUpdate(M,ft,Ie)),typeof I.componentDidUpdate=="function"&&(g.flags|=4),typeof I.getSnapshotBeforeUpdate=="function"&&(g.flags|=1024)):(typeof I.componentDidUpdate!="function"||J===h.memoizedProps&&st===h.memoizedState||(g.flags|=4),typeof I.getSnapshotBeforeUpdate!="function"||J===h.memoizedProps&&st===h.memoizedState||(g.flags|=1024),g.memoizedProps=M,g.memoizedState=ft),I.props=M,I.state=ft,I.context=Ie,M=yt):(typeof I.componentDidUpdate!="function"||J===h.memoizedProps&&st===h.memoizedState||(g.flags|=4),typeof I.getSnapshotBeforeUpdate!="function"||J===h.memoizedProps&&st===h.memoizedState||(g.flags|=1024),M=!1)}return I=M,wv(h,g),M=(g.flags&128)!==0,I||M?(I=g.stateNode,_=M&&typeof _.getDerivedStateFromError!="function"?null:I.render(),g.flags|=1,h!==null&&M?(g.child=Sh(g,h.child,null,P),g.child=Sh(g,null,_,P)):ca(h,g,_,P),g.memoizedState=I.state,h=g.child):h=uc(h,g,P),h}function B5(h,g,_,M){return xh(),g.flags|=256,ca(h,g,_,M),g.child}var EE={dehydrated:null,treeContext:null,retryLane:0,hydrationErrors:null};function TE(h){return{baseLanes:h,cachePool:kI()}}function AE(h,g,_){return h=h!==null?h.childLanes&~_:0,g&&(h|=Ps),h}function $5(h,g,_){var M=g.pendingProps,P=!1,I=(g.flags&128)!==0,J;if((J=I)||(J=h!==null&&h.memoizedState===null?!1:(oi.current&2)!==0),J&&(P=!0,g.flags&=-129),J=(g.flags&32)!==0,g.flags&=-33,h===null){if(Un){if(P?ku(g):ju(),(h=Tr)?(h=YF(h,io),h=h!==null&&h.data!=="&"?h:null,h!==null&&(g.memoizedState={dehydrated:h,treeContext:Su!==null?{id:gl,overflow:xl}:null,retryLane:536870912,hydrationErrors:null},_=_I(h),_.return=g,g.child=_,oa=g,Tr=null)):h=null,h===null)throw Mu(g);return uT(h)?g.lanes=32:g.lanes=536870912,null}var ge=M.children;return M=M.fallback,P?(ju(),P=g.mode,ge=Sv({mode:"hidden",children:ge},P),M=gh(M,P,_,null),ge.return=g,M.return=g,ge.sibling=M,g.child=ge,M=g.child,M.memoizedState=TE(_),M.childLanes=AE(h,J,_),g.memoizedState=EE,Cx(null,M)):(ku(g),CE(g,ge))}var Ie=h.memoizedState;if(Ie!==null&&(ge=Ie.dehydrated,ge!==null)){if(I)g.flags&256?(ku(g),g.flags&=-257,g=kE(h,g,_)):g.memoizedState!==null?(ju(),g.child=h.child,g.flags|=128,g=null):(ju(),ge=M.fallback,P=g.mode,M=Sv({mode:"visible",children:M.children},P),ge=gh(ge,P,_,null),ge.flags|=2,M.return=g,ge.return=g,M.sibling=ge,g.child=M,Sh(g,h.child,null,_),M=g.child,M.memoizedState=TE(_),M.childLanes=AE(h,J,_),g.memoizedState=EE,g=Cx(null,M));else if(ku(g),uT(ge)){if(J=ge.nextSibling&&ge.nextSibling.dataset,J)var it=J.dgst;J=it,M=Error(r(419)),M.stack="",M.digest=J,xx({value:M,source:null,stack:null}),g=kE(h,g,_)}else if(pi||gm(h,g,_,!1),J=(_&h.childLanes)!==0,pi||J){if(J=yr,J!==null&&(M=Gt(J,_),M!==0&&M!==Ie.retryLane))throw Ie.retryLane=M,ph(h,M),cs(J,h,M),NE;cT(ge)||Pv(),g=kE(h,g,_)}else cT(ge)?(g.flags|=192,g.child=h.child,g=null):(h=Ie.treeContext,Tr=so(ge.nextSibling),oa=g,Un=!0,Nu=null,io=!1,h!==null&&NI(g,h),g=CE(g,M.children),g.flags|=4096);return g}return P?(ju(),ge=M.fallback,P=g.mode,Ie=h.child,it=Ie.sibling,M=ic(Ie,{mode:"hidden",children:M.children}),M.subtreeFlags=Ie.subtreeFlags&65011712,it!==null?ge=ic(it,ge):(ge=gh(ge,P,_,null),ge.flags|=2),ge.return=g,M.return=g,M.sibling=ge,g.child=M,Cx(null,M),M=g.child,ge=h.child.memoizedState,ge===null?ge=TE(_):(P=ge.cachePool,P!==null?(Ie=fi._currentValue,P=P.parent!==Ie?{parent:Ie,pool:Ie}:P):P=kI(),ge={baseLanes:ge.baseLanes|_,cachePool:P}),M.memoizedState=ge,M.childLanes=AE(h,J,_),g.memoizedState=EE,Cx(h.child,M)):(ku(g),_=h.child,h=_.sibling,_=ic(_,{mode:"visible",children:M.children}),_.return=g,_.sibling=null,h!==null&&(J=g.deletions,J===null?(g.deletions=[h],g.flags|=16):J.push(h)),g.child=_,g.memoizedState=null,_)}function CE(h,g){return g=Sv({mode:"visible",children:g},h.mode),g.return=h,h.child=g}function Sv(h,g){return h=As(22,h,null,g),h.lanes=0,h}function kE(h,g,_){return Sh(g,h.child,null,_),h=CE(g,g.pendingProps.children),h.flags|=2,g.memoizedState=null,h}function H5(h,g,_){h.lanes|=g;var M=h.alternate;M!==null&&(M.lanes|=g),GM(h.return,g,_)}function jE(h,g,_,M,P,I){var J=h.memoizedState;J===null?h.memoizedState={isBackwards:g,rendering:null,renderingStartTime:0,last:M,tail:_,tailMode:P,treeForkCount:I}:(J.isBackwards=g,J.rendering=null,J.renderingStartTime=0,J.last=M,J.tail=_,J.tailMode=P,J.treeForkCount=I)}function V5(h,g,_){var M=g.pendingProps,P=M.revealOrder,I=M.tail;M=M.children;var J=oi.current,ge=(J&2)!==0;if(ge?(J=J&1|2,g.flags|=128):J&=1,ae(oi,J),ca(h,g,M,_),M=Un?gx:0,!ge&&h!==null&&(h.flags&128)!==0)e:for(h=g.child;h!==null;){if(h.tag===13)h.memoizedState!==null&&H5(h,_,g);else if(h.tag===19)H5(h,_,g);else if(h.child!==null){h.child.return=h,h=h.child;continue}if(h===g)break e;for(;h.sibling===null;){if(h.return===null||h.return===g)break e;h=h.return}h.sibling.return=h.return,h=h.sibling}switch(P){case"forwards":for(_=g.child,P=null;_!==null;)h=_.alternate,h!==null&&dv(h)===null&&(P=_),_=_.sibling;_=P,_===null?(P=g.child,g.child=null):(P=_.sibling,_.sibling=null),jE(g,!1,P,_,I,M);break;case"backwards":case"unstable_legacy-backwards":for(_=null,P=g.child,g.child=null;P!==null;){if(h=P.alternate,h!==null&&dv(h)===null){g.child=P;break}h=P.sibling,P.sibling=_,_=P,P=h}jE(g,!0,_,null,I,M);break;case"together":jE(g,!1,null,null,void 0,M);break;default:g.memoizedState=null}return g.child}function uc(h,g,_){if(h!==null&&(g.dependencies=h.dependencies),Du|=g.lanes,(_&g.childLanes)===0)if(h!==null){if(gm(h,g,_,!1),(_&g.childLanes)===0)return null}else return null;if(h!==null&&g.child!==h.child)throw Error(r(153));if(g.child!==null){for(h=g.child,_=ic(h,h.pendingProps),g.child=_,_.return=g;h.sibling!==null;)h=h.sibling,_=_.sibling=ic(h,h.pendingProps),_.return=g;_.sibling=null}return g.child}function PE(h,g){return(h.lanes&g)!==0?!0:(h=h.dependencies,!!(h!==null&&rv(h)))}function Cie(h,g,_){switch(g.tag){case 3:Me(g,g.stateNode.containerInfo),Eu(g,fi,h.memoizedState.cache),xh();break;case 27:case 5:Ee(g);break;case 4:Me(g,g.stateNode.containerInfo);break;case 10:Eu(g,g.type,g.memoizedProps.value);break;case 31:if(g.memoizedState!==null)return g.flags|=128,rE(g),null;break;case 13:var M=g.memoizedState;if(M!==null)return M.dehydrated!==null?(ku(g),g.flags|=128,null):(_&g.child.childLanes)!==0?$5(h,g,_):(ku(g),h=uc(h,g,_),h!==null?h.sibling:null);ku(g);break;case 19:var P=(h.flags&128)!==0;if(M=(_&g.childLanes)!==0,M||(gm(h,g,_,!1),M=(_&g.childLanes)!==0),P){if(M)return V5(h,g,_);g.flags|=128}if(P=g.memoizedState,P!==null&&(P.rendering=null,P.tail=null,P.lastEffect=null),ae(oi,oi.current),M)break;return null;case 22:return g.lanes=0,L5(h,g,_,g.pendingProps);case 24:Eu(g,fi,h.memoizedState.cache)}return uc(h,g,_)}function G5(h,g,_){if(h!==null)if(h.memoizedProps!==g.pendingProps)pi=!0;else{if(!PE(h,_)&&(g.flags&128)===0)return pi=!1,Cie(h,g,_);pi=(h.flags&131072)!==0}else pi=!1,Un&&(g.flags&1048576)!==0&&SI(g,gx,g.index);switch(g.lanes=0,g.tag){case 16:e:{var M=g.pendingProps;if(h=_h(g.elementType),g.type=h,typeof h=="function")IM(h)?(M=Mh(h,M),g.tag=1,g=z5(null,g,h,M,_)):(g.tag=0,g=ME(null,g,h,M,_));else{if(h!=null){var P=h.$$typeof;if(P===T){g.tag=11,g=R5(null,g,h,M,_);break e}else if(P===A){g.tag=14,g=D5(null,g,h,M,_);break e}}throw g=j(h)||h,Error(r(306,g,""))}}return g;case 0:return ME(h,g,g.type,g.pendingProps,_);case 1:return M=g.type,P=Mh(M,g.pendingProps),z5(h,g,M,P,_);case 3:e:{if(Me(g,g.stateNode.containerInfo),h===null)throw Error(r(387));M=g.pendingProps;var I=g.memoizedState;P=I.element,ZM(h,g),Nx(g,M,null,_);var J=g.memoizedState;if(M=J.cache,Eu(g,fi,M),M!==I.cache&&WM(g,[fi],_,!0),Sx(),M=J.element,I.isDehydrated)if(I={element:M,isDehydrated:!1,cache:J.cache},g.updateQueue.baseState=I,g.memoizedState=I,g.flags&256){g=B5(h,g,M,_);break e}else if(M!==P){P=to(Error(r(424)),g),xx(P),g=B5(h,g,M,_);break e}else{switch(h=g.stateNode.containerInfo,h.nodeType){case 9:h=h.body;break;default:h=h.nodeName==="HTML"?h.ownerDocument.body:h}for(Tr=so(h.firstChild),oa=g,Un=!0,Nu=null,io=!0,_=LI(g,null,M,_),g.child=_;_;)_.flags=_.flags&-3|4096,_=_.sibling}else{if(xh(),M===P){g=uc(h,g,_);break e}ca(h,g,M,_)}g=g.child}return g;case 26:return wv(h,g),h===null?(_=nU(g.type,null,g.pendingProps,null))?g.memoizedState=_:Un||(_=g.type,h=g.pendingProps,M=Uv(pe.current).createElement(_),M[sn]=g,M[Sr]=h,ua(M,_,h),He(M),g.stateNode=M):g.memoizedState=nU(g.type,h.memoizedProps,g.pendingProps,h.memoizedState),null;case 27:return Ee(g),h===null&&Un&&(M=g.stateNode=JF(g.type,g.pendingProps,pe.current),oa=g,io=!0,P=Tr,Uu(g.type)?(dT=P,Tr=so(M.firstChild)):Tr=P),ca(h,g,g.pendingProps.children,_),wv(h,g),h===null&&(g.flags|=4194304),g.child;case 5:return h===null&&Un&&((P=M=Tr)&&(M=aae(M,g.type,g.pendingProps,io),M!==null?(g.stateNode=M,oa=g,Tr=so(M.firstChild),io=!1,P=!0):P=!1),P||Mu(g)),Ee(g),P=g.type,I=g.pendingProps,J=h!==null?h.memoizedProps:null,M=I.children,sT(P,I)?M=null:J!==null&&sT(P,J)&&(g.flags|=32),g.memoizedState!==null&&(P=aE(h,g,vie,null,null,_),Vx._currentValue=P),wv(h,g),ca(h,g,M,_),g.child;case 6:return h===null&&Un&&((h=_=Tr)&&(_=sae(_,g.pendingProps,io),_!==null?(g.stateNode=_,oa=g,Tr=null,h=!0):h=!1),h||Mu(g)),null;case 13:return $5(h,g,_);case 4:return Me(g,g.stateNode.containerInfo),M=g.pendingProps,h===null?g.child=Sh(g,null,M,_):ca(h,g,M,_),g.child;case 11:return R5(h,g,g.type,g.pendingProps,_);case 7:return ca(h,g,g.pendingProps,_),g.child;case 8:return ca(h,g,g.pendingProps.children,_),g.child;case 12:return ca(h,g,g.pendingProps.children,_),g.child;case 10:return M=g.pendingProps,Eu(g,g.type,M.value),ca(h,g,M.children,_),g.child;case 9:return P=g.type._context,M=g.pendingProps.children,yh(g),P=la(P),M=M(P),g.flags|=1,ca(h,g,M,_),g.child;case 14:return D5(h,g,g.type,g.pendingProps,_);case 15:return O5(h,g,g.type,g.pendingProps,_);case 19:return V5(h,g,_);case 31:return Aie(h,g,_);case 22:return L5(h,g,_,g.pendingProps);case 24:return yh(g),M=la(fi),h===null?(P=XM(),P===null&&(P=yr,I=qM(),P.pooledCache=I,I.refCount++,I!==null&&(P.pooledCacheLanes|=_),P=I),g.memoizedState={parent:M,cache:P},QM(g),Eu(g,fi,P)):((h.lanes&_)!==0&&(ZM(h,g),Nx(g,null,null,_),Sx()),P=h.memoizedState,I=g.memoizedState,P.parent!==M?(P={parent:M,cache:M},g.memoizedState=P,g.lanes===0&&(g.memoizedState=g.updateQueue.baseState=P),Eu(g,fi,M)):(M=I.cache,Eu(g,fi,M),M!==P.cache&&WM(g,[fi],_,!0))),ca(h,g,g.pendingProps.children,_),g.child;case 29:throw g.pendingProps}throw Error(r(156,g.tag))}function dc(h){h.flags|=4}function RE(h,g,_,M,P){if((g=(h.mode&32)!==0)&&(g=!1),g){if(h.flags|=16777216,(P&335544128)===P)if(h.stateNode.complete)h.flags|=8192;else if(bF())h.flags|=8192;else throw wh=ov,YM}else h.flags&=-16777217}function W5(h,g){if(g.type!=="stylesheet"||(g.state.loading&4)!==0)h.flags&=-16777217;else if(h.flags|=16777216,!oU(g))if(bF())h.flags|=8192;else throw wh=ov,YM}function Nv(h,g){g!==null&&(h.flags|=4),h.flags&16384&&(g=h.tag!==22?Pt():536870912,h.lanes|=g,Am|=g)}function kx(h,g){if(!Un)switch(h.tailMode){case"hidden":g=h.tail;for(var _=null;g!==null;)g.alternate!==null&&(_=g),g=g.sibling;_===null?h.tail=null:_.sibling=null;break;case"collapsed":_=h.tail;for(var M=null;_!==null;)_.alternate!==null&&(M=_),_=_.sibling;M===null?g||h.tail===null?h.tail=null:h.tail.sibling=null:M.sibling=null}}function Ar(h){var g=h.alternate!==null&&h.alternate.child===h.child,_=0,M=0;if(g)for(var P=h.child;P!==null;)_|=P.lanes|P.childLanes,M|=P.subtreeFlags&65011712,M|=P.flags&65011712,P.return=h,P=P.sibling;else for(P=h.child;P!==null;)_|=P.lanes|P.childLanes,M|=P.subtreeFlags,M|=P.flags,P.return=h,P=P.sibling;return h.subtreeFlags|=M,h.childLanes=_,g}function kie(h,g,_){var M=g.pendingProps;switch(BM(g),g.tag){case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return Ar(g),null;case 1:return Ar(g),null;case 3:return _=g.stateNode,M=null,h!==null&&(M=h.memoizedState.cache),g.memoizedState.cache!==M&&(g.flags|=2048),oc(fi),me(),_.pendingContext&&(_.context=_.pendingContext,_.pendingContext=null),(h===null||h.child===null)&&(pm(g)?dc(g):h===null||h.memoizedState.isDehydrated&&(g.flags&256)===0||(g.flags|=1024,HM())),Ar(g),null;case 26:var P=g.type,I=g.memoizedState;return h===null?(dc(g),I!==null?(Ar(g),W5(g,I)):(Ar(g),RE(g,P,null,M,_))):I?I!==h.memoizedState?(dc(g),Ar(g),W5(g,I)):(Ar(g),g.flags&=-16777217):(h=h.memoizedProps,h!==M&&dc(g),Ar(g),RE(g,P,h,M,_)),null;case 27:if(fe(g),_=pe.current,P=g.type,h!==null&&g.stateNode!=null)h.memoizedProps!==M&&dc(g);else{if(!M){if(g.stateNode===null)throw Error(r(166));return Ar(g),null}h=se.current,pm(g)?MI(g):(h=JF(P,M,_),g.stateNode=h,dc(g))}return Ar(g),null;case 5:if(fe(g),P=g.type,h!==null&&g.stateNode!=null)h.memoizedProps!==M&&dc(g);else{if(!M){if(g.stateNode===null)throw Error(r(166));return Ar(g),null}if(I=se.current,pm(g))MI(g);else{var J=Uv(pe.current);switch(I){case 1:I=J.createElementNS("http://www.w3.org/2000/svg",P);break;case 2:I=J.createElementNS("http://www.w3.org/1998/Math/MathML",P);break;default:switch(P){case"svg":I=J.createElementNS("http://www.w3.org/2000/svg",P);break;case"math":I=J.createElementNS("http://www.w3.org/1998/Math/MathML",P);break;case"script":I=J.createElement("div"),I.innerHTML=" - + +