diff --git a/CHANGELOG.md b/CHANGELOG.md index 261b331f6..3d64672a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,8 +15,10 @@ All notable changes to Bambuddy will be documented in this file. - **Dual External Spool Support for H2D** — H2-series printers with two external spool holders (Ext-L and Ext-R) are now fully supported. The external spool section renders as a grid with both slots, each showing filament type, color, fill level, and hover card details. Previously only a single external spool was displayed. Applies to the printer card, filament mapping, print scheduler, usage tracking, and inventory assignment. The `vt_tray` field is now an array across the entire stack (MQTT, API, WebSocket, frontend). - **AMS Slot Configuration — Model Filtering & Pre-Population** — The Configure AMS Slot modal now filters filament presets by the connected printer model. Only presets matching the printer (e.g., "@BBL X1C" presets for X1C printers) and generic presets without a model suffix are shown. Local presets are filtered by their `compatible_printers` field. When re-configuring an already-configured slot, the modal pre-selects the saved preset, pre-populates the color, and auto-selects the active K-profile. The preset list auto-scrolls to the selected item. All modal strings are now fully translated in 5 locales (en, de, fr, it, ja). - **K-Profiles View — Accurate Filament Name Resolution** — K-profile filament names are now resolved from builtin filament tables and user cloud presets (via new `/cloud/filament-id-map` endpoint) instead of showing raw IDs like "GFU99" or "P4d64437". Falls back to extracting names from the profile name field. +- **Print Log** — New view mode on the Archives page showing a chronological table of all print activity. Columns include date/time, print name, printer, user, status, duration, and filament. Supports filtering by search text, printer, user, status, and date range. Pagination with configurable page size. A dedicated clear button deletes only log entries without affecting archives. Data is stored in a separate `print_log_entries` database table. ### Fixed +- **Firmware Upload Uses Wrong Filename on Cache Hit** — The firmware update uploader cached downloaded firmware files under a mangled name (e.g., `X1C_01_09_00_10.bin`) instead of the original filename from Bambu Lab's CDN. On the first download the correct filename was uploaded to the SD card, but on subsequent attempts the cached file with the wrong name was used — causing the printer to not recognize the firmware file. Now caches using the original filename so the SD card always receives the correct file. - **Update Check Runs When Disabled** ([#367](https://github.com/maziggy/bambuddy/issues/367)) — The Settings page triggered an update check on every visit even when "Check for updates" was disabled, causing error popups on air-gapped systems with no internet. The backend `/updates/check` endpoint also ignored the setting entirely. Now the backend returns early without making GitHub API calls when the setting is disabled, the Settings page respects the `check_updates` flag before auto-fetching, and the printer card firmware badge shows a neutral version-only display instead of disappearing when firmware update checks are off. - **Stale Inventory Assignments Persist After Switching to Spoolman Mode** — When switching from built-in inventory to Spoolman mode, existing spool-to-AMS-slot assignments were not cleaned up. The printer card hover cards continued showing "Assign Spool" buttons that opened the internal inventory modal, and any prior assignments remained visible. Now bulk-deletes all `SpoolAssignment` records when enabling Spoolman, invalidates the frontend cache so printer cards update immediately, and hides the inventory assign/unassign UI on printer cards while in Spoolman mode. - **Bulk Archive Delete Leaves Orphaned Database Records** — When bulk-deleting archives, the files were removed from disk before the database commit. If concurrent SQLite writes caused a lock timeout, the commit failed and rolled back — leaving database records pointing to deleted files (broken thumbnails, 404 errors). Fixed by deleting the database record first and only removing files after a successful commit. @@ -32,6 +34,7 @@ All notable changes to Bambuddy will be documented in this file. - **Reprint Fails with SD Card Error for Archives Without 3MF File** ([#376](https://github.com/maziggy/bambuddy/issues/376)) — When a print was sent from an external slicer and Bambuddy couldn't download the 3MF from the printer during auto-archiving, the fallback archive had no file. Attempting to reprint such an archive tried to upload the data directory as a file, causing a confusing "SD card error." The backend now returns a clear error for file-less archives, and the frontend disables Print/Schedule/Open in Slicer buttons with a tooltip explaining that the 3MF file is unavailable. - **Inventory Spool Weight Resets After Print Completes** — After a print, the usage tracker correctly updated `weight_used` (e.g., +1.6g), but periodic AMS status updates recalculated `weight_used` from the AMS remain% sensor and overwrote the precise value. For small prints on large spools (e.g., 1.6g on 1000g), the AMS remain% stays at 100% (integer resolution = 10g steps), resetting `weight_used` back to 0. The AMS weight sync now only increases `weight_used`, never decreases it, preserving precise values from the usage tracker. - **Loose Archive Name Matching Could Cause Wrong Archive Reuse** ([#374](https://github.com/maziggy/bambuddy/issues/374)) — The `on_print_start` callback used `ilike('%{name}%')` to find existing "printing" archives, which meant a print named "Clip" could incorrectly match "Cable Clip" or "Clip Stand". This could cause a new print to reuse the wrong archive or skip creating one. Tightened to exact `print_name` match or exact filename variants (`.3mf`, `.gcode.3mf`). +- **Archive Duplicate Badge Misses Name-Based Duplicates** ([#315](https://github.com/maziggy/bambuddy/issues/315)) — The duplicate badge on archive cards only matched by file content hash, so re-sliced prints of the same model (different GCODE, same print name) were not flagged as duplicates. Now also matches by print name (case-insensitive), consistent with the detail view's duplicate detection. ### Improved - **Phantom Print Investigation — Logging & Hardening** ([#374](https://github.com/maziggy/bambuddy/issues/374)) — Added targeted logging and hardening to help diagnose reports of prints starting automatically without user input. Debug log volume reduced ~90% by suppressing `sqlalchemy.engine` (changed from INFO to WARNING) and `aiosqlite` (new WARNING suppression) noise that previously filled 2.5MB in 16 minutes. Every `start_print()` call now logs a `PRINT COMMAND` trace with the caller's file, line, and function name. The print scheduler logs pending queue items when found. `on_print_complete` warns when multiple queue items are in "printing" status for the same printer, which signals a state inconsistency. diff --git a/README.md b/README.md index a986ea7b7..9a0ab62fd 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,7 @@ Perfect for remote print farms, traveling makers, or accessing your home printer - Plate thumbnail browsing for multi-plate archives (hover to navigate between plates) - Archive comparison (side-by-side diff) - Tag management (rename/delete across all archives) +- **Print Log** — Chronological table view of all print activity with columns for date/time, print name, printer, user, status, duration, and filament. Filterable by search, printer, user, status, and date range. Pagination with configurable page size. Clear button removes log entries without affecting archives. ### 📊 Monitoring & Control - Real-time printer status via WebSocket diff --git a/backend/app/api/routes/archives.py b/backend/app/api/routes/archives.py index c5f6e409d..abe2aa221 100644 --- a/backend/app/api/routes/archives.py +++ b/backend/app/api/routes/archives.py @@ -134,13 +134,15 @@ async def list_archives( offset=offset, ) - # Get set of hashes that have duplicates (efficient single query) - duplicate_hashes = await service.get_duplicate_hashes() + # Get sets of hashes and names that have duplicates (efficient single queries) + duplicate_hashes, duplicate_names = await service.get_duplicate_hashes_and_names() - # Mark archives that have duplicates + # Mark archives that have duplicates (by hash or by print name) result = [] for a in archives: - has_duplicate = a.content_hash in duplicate_hashes if a.content_hash else False + has_hash_dup = a.content_hash in duplicate_hashes if a.content_hash else False + has_name_dup = a.print_name and a.print_name.lower() in duplicate_names + has_duplicate = has_hash_dup or has_name_dup result.append(archive_to_response(a, duplicate_count=1 if has_duplicate else 0)) return result diff --git a/backend/app/api/routes/print_log.py b/backend/app/api/routes/print_log.py new file mode 100644 index 000000000..51fc5451a --- /dev/null +++ b/backend/app/api/routes/print_log.py @@ -0,0 +1,129 @@ +import logging +from datetime import datetime + +from fastapi import APIRouter, Depends, HTTPException, Query +from fastapi.responses import FileResponse +from sqlalchemy import delete, func, select +from sqlalchemy.ext.asyncio import AsyncSession + +from backend.app.core.auth import RequirePermissionIfAuthEnabled +from backend.app.core.config import settings +from backend.app.core.database import get_db +from backend.app.core.permissions import Permission +from backend.app.models.print_log import PrintLogEntry +from backend.app.models.user import User +from backend.app.schemas.print_log import PrintLogEntrySchema, PrintLogResponse + +logger = logging.getLogger(__name__) + +router = APIRouter(prefix="/print-log", tags=["print-log"]) + + +@router.get("/", response_model=PrintLogResponse) +async def get_print_log( + search: str | None = None, + printer_id: int | None = None, + created_by_username: str | None = None, + status: str | None = None, + date_from: datetime | None = None, + date_to: datetime | None = None, + limit: int = Query(default=50, ge=1, le=500), + offset: int = Query(default=0, ge=0), + db: AsyncSession = Depends(get_db), + _: User | None = RequirePermissionIfAuthEnabled(Permission.ARCHIVES_READ), +): + """Get the print log.""" + query = select(PrintLogEntry) + count_query = select(func.count(PrintLogEntry.id)) + + if printer_id is not None: + query = query.where(PrintLogEntry.printer_id == printer_id) + count_query = count_query.where(PrintLogEntry.printer_id == printer_id) + if created_by_username: + query = query.where(PrintLogEntry.created_by_username == created_by_username) + count_query = count_query.where(PrintLogEntry.created_by_username == created_by_username) + if status: + query = query.where(PrintLogEntry.status == status) + count_query = count_query.where(PrintLogEntry.status == status) + if search: + query = query.where(PrintLogEntry.print_name.ilike(f"%{search}%")) + count_query = count_query.where(PrintLogEntry.print_name.ilike(f"%{search}%")) + if date_from: + query = query.where(PrintLogEntry.created_at >= date_from) + count_query = count_query.where(PrintLogEntry.created_at >= date_from) + if date_to: + query = query.where(PrintLogEntry.created_at <= date_to) + count_query = count_query.where(PrintLogEntry.created_at <= date_to) + + # Get total count + total_result = await db.execute(count_query) + total = total_result.scalar() or 0 + + # Get paginated results + query = query.order_by(PrintLogEntry.created_at.desc()).offset(offset).limit(limit) + result = await db.execute(query) + entries = result.scalars().all() + + return PrintLogResponse( + items=[ + PrintLogEntrySchema( + id=e.id, + print_name=e.print_name, + printer_name=e.printer_name, + printer_id=e.printer_id, + status=e.status, + started_at=e.started_at, + completed_at=e.completed_at, + duration_seconds=e.duration_seconds, + filament_type=e.filament_type, + filament_color=e.filament_color, + filament_used_grams=e.filament_used_grams, + thumbnail_path=e.thumbnail_path, + created_by_username=e.created_by_username, + created_at=e.created_at, + ) + for e in entries + ], + total=total, + ) + + +@router.get("/{entry_id}/thumbnail") +async def get_print_log_thumbnail( + entry_id: int, + db: AsyncSession = Depends(get_db), +): + """Get the thumbnail for a print log entry. + + Note: Unauthenticated - loaded via tags which can't send auth headers. + """ + entry = await db.get(PrintLogEntry, entry_id) + if not entry or not entry.thumbnail_path: + raise HTTPException(404, "Thumbnail not found") + + thumb_path = settings.base_dir / entry.thumbnail_path + if not thumb_path.exists(): + raise HTTPException(404, "Thumbnail file not found") + + return FileResponse( + path=thumb_path, + media_type="image/png", + headers={"Cache-Control": "public, max-age=86400"}, + ) + + +@router.delete("/") +async def clear_print_log( + db: AsyncSession = Depends(get_db), + _: User | None = RequirePermissionIfAuthEnabled(Permission.ARCHIVES_DELETE_ALL), +): + """Clear the print log. + + Only deletes log entries. Archives and queue items are never touched. + """ + result = await db.execute(delete(PrintLogEntry)) + deleted = result.rowcount + await db.commit() + + logger.info("Print log cleared: %d entries deleted", deleted) + return {"deleted": deleted} diff --git a/backend/app/core/database.py b/backend/app/core/database.py index b34fef663..33e2e37a6 100644 --- a/backend/app/core/database.py +++ b/backend/app/core/database.py @@ -89,6 +89,7 @@ async def init_db(): notification_template, orca_base_cache, pending_upload, + print_log, print_queue, printer, project, diff --git a/backend/app/main.py b/backend/app/main.py index ca17c0118..d4fafdcab 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -194,6 +194,7 @@ from backend.app.api.routes import ( notification_templates, notifications, pending_uploads, + print_log, print_queue, printers, projects, @@ -1958,6 +1959,9 @@ async def on_print_complete(printer_id: int, data: dict): except Exception as e: logger.warning("[CALLBACK] WebSocket send_print_complete failed: %s", e) + # Capture user info before clearing (needed for print log entry) + _print_user_info = printer_manager.get_current_print_user(printer_id) + # Clear current print user tracking (Issue #206) printer_manager.clear_current_print_user(printer_id) @@ -2158,6 +2162,36 @@ async def on_print_complete(printer_id: int, data: dict): log_timing("Archive status update") + # Write independent print log entry (separate table, never touches archives) + try: + async with async_session() as db: + from backend.app.models.archive import PrintArchive + from backend.app.services.print_log import write_log_entry + + archive = await db.get(PrintArchive, archive_id) + if archive: + p_info = printer_manager.get_printer(printer_id) + await write_log_entry( + db, + status=data.get("status", "completed"), + print_name=archive.print_name, + printer_name=p_info.name if p_info else None, + printer_id=printer_id, + started_at=archive.started_at, + completed_at=archive.completed_at, + filament_type=archive.filament_type, + filament_color=archive.filament_color, + filament_used_grams=archive.filament_used_grams, + thumbnail_path=archive.thumbnail_path, + created_by_username=_print_user_info.get("username") if _print_user_info else None, + ) + await db.commit() + logger.info("[PRINT_LOG] Log entry written for archive %s", archive_id) + except Exception as e: + logger.warning("[PRINT_LOG] Failed to write log entry for archive %s: %s", archive_id, e) + + log_timing("Print log entry") + # Track filament consumption from AMS remain% deltas (skip if Spoolman handles usage) usage_results: list[dict] = [] try: @@ -3369,6 +3403,7 @@ app.include_router(settings_routes.router, prefix=app_settings.api_prefix) app.include_router(cloud.router, prefix=app_settings.api_prefix) app.include_router(local_presets.router, prefix=app_settings.api_prefix) app.include_router(smart_plugs.router, prefix=app_settings.api_prefix) +app.include_router(print_log.router, prefix=app_settings.api_prefix) app.include_router(print_queue.router, prefix=app_settings.api_prefix) app.include_router(kprofiles.router, prefix=app_settings.api_prefix) app.include_router(notifications.router, prefix=app_settings.api_prefix) diff --git a/backend/app/models/print_log.py b/backend/app/models/print_log.py new file mode 100644 index 000000000..c1ac0f20c --- /dev/null +++ b/backend/app/models/print_log.py @@ -0,0 +1,31 @@ +from datetime import datetime + +from sqlalchemy import DateTime, Float, Integer, String, func +from sqlalchemy.orm import Mapped, mapped_column + +from backend.app.core.database import Base + + +class PrintLogEntry(Base): + """Independent print log entry. Written when print events occur. + + This is a separate table from archives/queue — clearing the log + never touches archives or queue items. + """ + + __tablename__ = "print_log_entries" + + id: Mapped[int] = mapped_column(primary_key=True) + print_name: Mapped[str | None] = mapped_column(String(255)) + printer_name: Mapped[str | None] = mapped_column(String(255)) + printer_id: Mapped[int | None] = mapped_column(Integer) + status: Mapped[str] = mapped_column(String(20)) # completed, failed, stopped, cancelled, skipped + started_at: Mapped[datetime | None] = mapped_column(DateTime) + completed_at: Mapped[datetime | None] = mapped_column(DateTime) + duration_seconds: Mapped[int | None] = mapped_column(Integer) + filament_type: Mapped[str | None] = mapped_column(String(50)) + filament_color: Mapped[str | None] = mapped_column(String(50)) + filament_used_grams: Mapped[float | None] = mapped_column(Float) + thumbnail_path: Mapped[str | None] = mapped_column(String(500)) + created_by_username: Mapped[str | None] = mapped_column(String(100)) + created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now()) diff --git a/backend/app/schemas/print_log.py b/backend/app/schemas/print_log.py new file mode 100644 index 000000000..8e2494645 --- /dev/null +++ b/backend/app/schemas/print_log.py @@ -0,0 +1,25 @@ +from datetime import datetime + +from pydantic import BaseModel + + +class PrintLogEntrySchema(BaseModel): + id: int + print_name: str | None = None + printer_name: str | None = None + printer_id: int | None = None + status: str + started_at: datetime | None = None + completed_at: datetime | None = None + duration_seconds: int | None = None + filament_type: str | None = None + filament_color: str | None = None + filament_used_grams: float | None = None + thumbnail_path: str | None = None + created_by_username: str | None = None + created_at: datetime + + +class PrintLogResponse(BaseModel): + items: list[PrintLogEntrySchema] + total: int diff --git a/backend/app/services/archive.py b/backend/app/services/archive.py index 60317cfaa..a1dccf9be 100644 --- a/backend/app/services/archive.py +++ b/backend/app/services/archive.py @@ -727,10 +727,10 @@ class ArchiveService: sha256.update(chunk) return sha256.hexdigest() - async def get_duplicate_hashes(self) -> set[str]: - """Get all content hashes that appear more than once. + async def get_duplicate_hashes_and_names(self) -> tuple[set[str], set[str]]: + """Get all content hashes and print names that appear more than once. - Returns a set of hashes that have duplicates. + Returns a tuple of (duplicate_hashes, duplicate_names). """ from sqlalchemy import func @@ -740,7 +740,17 @@ class ArchiveService: .group_by(PrintArchive.content_hash) .having(func.count(PrintArchive.id) > 1) ) - return {row[0] for row in result.all()} + duplicate_hashes = {row[0] for row in result.all()} + + result = await self.db.execute( + select(func.lower(PrintArchive.print_name)) + .where(PrintArchive.print_name.isnot(None)) + .group_by(func.lower(PrintArchive.print_name)) + .having(func.count(PrintArchive.id) > 1) + ) + duplicate_names = {row[0] for row in result.all()} + + return duplicate_hashes, duplicate_names async def find_duplicates( self, diff --git a/backend/app/services/firmware_check.py b/backend/app/services/firmware_check.py index 9d8328900..412c295d2 100644 --- a/backend/app/services/firmware_check.py +++ b/backend/app/services/firmware_check.py @@ -324,14 +324,6 @@ class FirmwareCheckService: cache_dir.mkdir(parents=True, exist_ok=True) return cache_dir - def _get_cached_firmware_path(self, model: str, version: str) -> Path: - """Get the path where a firmware file would be cached.""" - # Normalize model name for filename - model_safe = model.upper().replace(" ", "-").replace("/", "-") - version_safe = version.replace(".", "_") - filename = f"{model_safe}_{version_safe}.bin" - return self._get_firmware_cache_dir() / filename - async def get_firmware_file_info(self, model: str) -> dict | None: """ Get information about the firmware file for a model. @@ -374,16 +366,16 @@ class FirmwareCheckService: logger.warning("No firmware download URL available for model: %s", model) return None - # Check if already cached - cached_path = self._get_cached_firmware_path(model, latest.version) - if cached_path.exists(): - logger.info("Using cached firmware: %s", cached_path) - return cached_path - # Extract original filename from URL (must preserve for SD card update) url_parts = latest.download_url.split("/") original_filename = url_parts[-1] if url_parts else f"firmware_{model}.bin" + # Check if already cached (using original filename so SD card gets the right name) + cached_path = self._get_firmware_cache_dir() / original_filename + if cached_path.exists(): + logger.info("Using cached firmware: %s", cached_path) + return cached_path + # Download to temp file first temp_path = self._get_firmware_cache_dir() / f".downloading_{original_filename}" @@ -407,22 +399,14 @@ class FirmwareCheckService: if progress_callback: progress_callback(downloaded, total_size, "Downloading firmware...") - # Also save a copy with the original filename for SD card - original_path = self._get_firmware_cache_dir() / original_filename - if original_path.exists(): - original_path.unlink() + # Move temp to final path, preserving original filename + temp_path.rename(cached_path) - # Move temp to both cached path and original filename path - import shutil - - shutil.copy2(temp_path, cached_path) - temp_path.rename(original_path) - - logger.info("Firmware downloaded successfully: %s", original_path) + logger.info("Firmware downloaded successfully: %s", cached_path) if progress_callback: progress_callback(downloaded, total_size, "Download complete") - return original_path + return cached_path except Exception as e: logger.error("Firmware download failed: %s", e) diff --git a/backend/app/services/print_log.py b/backend/app/services/print_log.py new file mode 100644 index 000000000..f3d68e2ae --- /dev/null +++ b/backend/app/services/print_log.py @@ -0,0 +1,52 @@ +"""Service for writing independent print log entries. + +Log entries are written to a separate table and never touch archives or queue items. +""" + +import logging +from datetime import datetime + +from sqlalchemy.ext.asyncio import AsyncSession + +from backend.app.models.print_log import PrintLogEntry + +logger = logging.getLogger(__name__) + + +async def write_log_entry( + db: AsyncSession, + *, + status: str, + print_name: str | None = None, + printer_name: str | None = None, + printer_id: int | None = None, + started_at: datetime | None = None, + completed_at: datetime | None = None, + filament_type: str | None = None, + filament_color: str | None = None, + filament_used_grams: float | None = None, + thumbnail_path: str | None = None, + created_by_username: str | None = None, +) -> PrintLogEntry: + """Write a print log entry.""" + duration = None + if started_at and completed_at: + duration = int((completed_at - started_at).total_seconds()) + + entry = PrintLogEntry( + print_name=print_name, + printer_name=printer_name, + printer_id=printer_id, + status=status, + started_at=started_at, + completed_at=completed_at, + duration_seconds=duration, + filament_type=filament_type, + filament_color=filament_color, + filament_used_grams=filament_used_grams, + thumbnail_path=thumbnail_path, + created_by_username=created_by_username, + ) + db.add(entry) + await db.flush() + return entry diff --git a/backend/tests/unit/test_print_log.py b/backend/tests/unit/test_print_log.py new file mode 100644 index 000000000..58358dc7c --- /dev/null +++ b/backend/tests/unit/test_print_log.py @@ -0,0 +1,104 @@ +"""Unit tests for print log service and schema.""" + +from datetime import datetime, timedelta + +import pytest + +from backend.app.schemas.print_log import PrintLogEntrySchema, PrintLogResponse + + +class TestPrintLogEntrySchema: + """Test PrintLogEntrySchema validation.""" + + def test_minimal_entry(self): + """Schema accepts minimal required fields.""" + entry = PrintLogEntrySchema( + id=1, + status="completed", + created_at=datetime(2024, 1, 15, 10, 30, 0), + ) + assert entry.id == 1 + assert entry.status == "completed" + assert entry.print_name is None + assert entry.printer_name is None + assert entry.duration_seconds is None + + def test_full_entry(self): + """Schema accepts all fields.""" + started = datetime(2024, 1, 15, 10, 0, 0) + completed = datetime(2024, 1, 15, 12, 30, 0) + entry = PrintLogEntrySchema( + id=42, + print_name="Benchy", + printer_name="X1C-01", + printer_id=3, + status="completed", + started_at=started, + completed_at=completed, + duration_seconds=9000, + filament_type="PLA", + filament_color="#FF5500", + filament_used_grams=15.2, + thumbnail_path="archives/3/20240115_benchy/thumbnail.png", + created_by_username="admin", + created_at=datetime(2024, 1, 15, 12, 30, 0), + ) + assert entry.print_name == "Benchy" + assert entry.printer_name == "X1C-01" + assert entry.filament_used_grams == 15.2 + assert entry.created_by_username == "admin" + + def test_failed_status(self): + """Schema accepts various status values.""" + for status in ("completed", "failed", "stopped", "cancelled", "skipped"): + entry = PrintLogEntrySchema(id=1, status=status, created_at=datetime.now()) + assert entry.status == status + + +class TestPrintLogResponse: + """Test PrintLogResponse pagination wrapper.""" + + def test_empty_response(self): + """Empty response with zero total.""" + resp = PrintLogResponse(items=[], total=0) + assert len(resp.items) == 0 + assert resp.total == 0 + + def test_paginated_response(self): + """Response with items and total count > items count.""" + items = [PrintLogEntrySchema(id=i, status="completed", created_at=datetime.now()) for i in range(3)] + resp = PrintLogResponse(items=items, total=100) + assert len(resp.items) == 3 + assert resp.total == 100 + + +class TestWriteLogEntry: + """Test the write_log_entry service function (logic only, no DB).""" + + def test_duration_calculation(self): + """Duration is computed from started_at and completed_at.""" + started = datetime(2024, 1, 15, 10, 0, 0) + completed = started + timedelta(hours=2, minutes=30) + + # Simulating the duration calculation from write_log_entry + duration = int((completed - started).total_seconds()) + assert duration == 9000 # 2.5 hours = 9000 seconds + + def test_duration_none_when_missing_times(self): + """Duration is None when started_at or completed_at is missing.""" + started = datetime(2024, 1, 15, 10, 0, 0) + completed_at = None + started_at = None + completed = datetime.now() + + # No completed_at + duration = None + if started and completed_at: + duration = int((completed_at - started).total_seconds()) + assert duration is None + + # No started_at + duration = None + if started_at and completed: + duration = int((completed - started_at).total_seconds()) + assert duration is None diff --git a/frontend/src/api/client.ts b/frontend/src/api/client.ts index 7da99aaaa..65f054366 100644 --- a/frontend/src/api/client.ts +++ b/frontend/src/api/client.ts @@ -369,6 +369,28 @@ export interface Archive { created_by_username: string | null; } +export interface PrintLogEntry { + id: number; + print_name: string | null; + printer_name: string | null; + printer_id: number | null; + status: string; + started_at: string | null; + completed_at: string | null; + duration_seconds: number | null; + filament_type: string | null; + filament_color: string | null; + filament_used_grams: number | null; + thumbnail_path: string | null; + created_by_username: string | null; + created_at: string; +} + +export interface PrintLogResponse { + items: PrintLogEntry[]; + total: number; +} + export interface ArchiveStats { total_prints: number; successful_prints: number; @@ -2954,6 +2976,32 @@ export const api = { return response.json(); }, + // Print Log + getPrintLog: (params?: { + search?: string; + printerId?: number; + username?: string; + status?: string; + dateFrom?: string; + dateTo?: string; + limit?: number; + offset?: number; + }) => { + const searchParams = new URLSearchParams(); + if (params?.search) searchParams.set('search', params.search); + if (params?.printerId) searchParams.set('printer_id', String(params.printerId)); + if (params?.username) searchParams.set('created_by_username', params.username); + if (params?.status) searchParams.set('status', params.status); + if (params?.dateFrom) searchParams.set('date_from', params.dateFrom); + if (params?.dateTo) searchParams.set('date_to', params.dateTo); + if (params?.limit) searchParams.set('limit', String(params.limit)); + if (params?.offset !== undefined) searchParams.set('offset', String(params.offset)); + return request(`/print-log/?${searchParams}`); + }, + getPrintLogThumbnail: (id: number) => `${API_BASE}/print-log/${id}/thumbnail`, + clearPrintLog: () => + request<{ deleted: number }>('/print-log/', { method: 'DELETE' }), + // Settings getSettings: () => request('/settings/'), updateSettings: (data: AppSettingsUpdate) => diff --git a/frontend/src/components/Layout.tsx b/frontend/src/components/Layout.tsx index 4ede5f234..614a2fdf2 100644 --- a/frontend/src/components/Layout.tsx +++ b/frontend/src/components/Layout.tsx @@ -1,6 +1,6 @@ import { useState, useEffect, useCallback, useRef, useMemo } from 'react'; import { NavLink, Outlet, useNavigate, useLocation } from 'react-router-dom'; -import { Printer, Archive, Calendar, BarChart3, Cloud, Settings, Sun, Moon, ChevronLeft, ChevronRight, Keyboard, Github, GripVertical, ArrowUpCircle, Wrench, FolderKanban, FolderOpen, X, Menu, Info, Plug, Bug, LogOut, Key, Loader2, Package, type LucideIcon } from 'lucide-react'; +import { Printer, Archive, Calendar, BarChart3, Cloud, Settings, Sun, Moon, ChevronLeft, ChevronRight, Keyboard, Github, GripVertical, ArrowUpCircle, Wrench, FolderKanban, FolderOpen, X, Menu, Info, Plug, Bug, LogOut, Key, Loader2, Disc3, type LucideIcon } from 'lucide-react'; import { useTranslation } from 'react-i18next'; import { useTheme } from '../contexts/ThemeContext'; import { KeyboardShortcutsModal } from './KeyboardShortcutsModal'; @@ -29,7 +29,7 @@ export const defaultNavItems: NavItem[] = [ { id: 'profiles', to: '/profiles', icon: Cloud, labelKey: 'nav.profiles' }, { id: 'maintenance', to: '/maintenance', icon: Wrench, labelKey: 'nav.maintenance' }, { id: 'projects', to: '/projects', icon: FolderKanban, labelKey: 'nav.projects' }, - { id: 'inventory', to: '/inventory', icon: Package, labelKey: 'nav.inventory' }, + { id: 'inventory', to: '/inventory', icon: Disc3, labelKey: 'nav.inventory' }, { id: 'files', to: '/files', icon: FolderOpen, labelKey: 'nav.files' }, { id: 'settings', to: '/settings', icon: Settings, labelKey: 'nav.settings' }, ]; diff --git a/frontend/src/i18n/locales/de.ts b/frontend/src/i18n/locales/de.ts index ea1edb67d..d8dd06b1c 100644 --- a/frontend/src/i18n/locales/de.ts +++ b/frontend/src/i18n/locales/de.ts @@ -484,6 +484,7 @@ export default { gridView: 'Rasteransicht', listView: 'Listenansicht', calendarView: 'Kalenderansicht', + logView: 'Druckprotokoll', manageTags: 'Tags verwalten', showFailedPrints: 'Fehlgeschlagene Drucke anzeigen', hideFailedPrints: 'Fehlgeschlagene Drucke ausblenden', @@ -672,6 +673,34 @@ export default { actions: 'Aktionen', hasTimelapse: 'Hat Zeitraffer', }, + log: { + date: 'Datum', + printName: 'Druckname', + printer: 'Drucker', + user: 'Benutzer', + status: 'Status', + duration: 'Dauer', + filament: 'Filament', + allPrinters: 'Alle Drucker', + allUsers: 'Alle Benutzer', + allStatuses: 'Alle Status', + cancelled: 'Abgebrochen', + skipped: 'Übersprungen', + dateFrom: 'Von', + dateTo: 'Bis', + noEntries: 'Keine Druckprotokolleinträge gefunden', + showing: '{{count}} von {{total}} Einträgen', + rowsPerPage: 'Zeilen', + page: 'Seite', + prev: 'Zurück', + next: 'Weiter', + clearLog: 'Protokoll löschen', + clearLogTitle: 'Druckprotokoll löschen', + clearLogConfirm: 'Alle Druckprotokolleinträge werden dauerhaft gelöscht. Archive und Warteschlangeneinträge sind nicht betroffen. Diese Aktion kann nicht rückgängig gemacht werden. Sind Sie sicher?', + clearLogButton: 'Alle löschen', + cleared: '{{count}} Protokolleinträge gelöscht', + clearFailed: 'Druckprotokoll konnte nicht gelöscht werden', + }, }, // Queue page diff --git a/frontend/src/i18n/locales/en.ts b/frontend/src/i18n/locales/en.ts index 54fbc783b..4cb043511 100644 --- a/frontend/src/i18n/locales/en.ts +++ b/frontend/src/i18n/locales/en.ts @@ -484,6 +484,7 @@ export default { gridView: 'Grid view', listView: 'List view', calendarView: 'Calendar view', + logView: 'Print Log', manageTags: 'Manage Tags', showFailedPrints: 'Show failed prints', hideFailedPrints: 'Hide failed prints', @@ -672,6 +673,34 @@ export default { actions: 'Actions', hasTimelapse: 'Has timelapse', }, + log: { + date: 'Date', + printName: 'Print Name', + printer: 'Printer', + user: 'User', + status: 'Status', + duration: 'Duration', + filament: 'Filament', + allPrinters: 'All Printers', + allUsers: 'All Users', + allStatuses: 'All Statuses', + cancelled: 'Cancelled', + skipped: 'Skipped', + dateFrom: 'From', + dateTo: 'To', + noEntries: 'No print log entries found', + showing: 'Showing {{count}} of {{total}} entries', + rowsPerPage: 'Rows', + page: 'Page', + prev: 'Prev', + next: 'Next', + clearLog: 'Clear Log', + clearLogTitle: 'Clear Print Log', + clearLogConfirm: 'All print log entries will be permanently deleted. Archives and queue items are not affected. This action cannot be undone. Are you sure?', + clearLogButton: 'Clear All', + cleared: '{{count}} log entries cleared', + clearFailed: 'Failed to clear print log', + }, }, // Queue page diff --git a/frontend/src/i18n/locales/fr.ts b/frontend/src/i18n/locales/fr.ts index 399039601..aef55a3e0 100644 --- a/frontend/src/i18n/locales/fr.ts +++ b/frontend/src/i18n/locales/fr.ts @@ -484,6 +484,7 @@ export default { gridView: 'Grille', listView: 'Liste', calendarView: 'Calendrier', + logView: 'Journal d\'impression', manageTags: 'Gérer les tags', showFailedPrints: 'Afficher les échecs', hideFailedPrints: 'Masquer les échecs', @@ -672,6 +673,34 @@ export default { actions: 'Actions', hasTimelapse: 'A un timelapse', }, + log: { + date: 'Date', + printName: 'Nom de l\'impression', + printer: 'Imprimante', + user: 'Utilisateur', + status: 'Statut', + duration: 'Durée', + filament: 'Filament', + allPrinters: 'Toutes les imprimantes', + allUsers: 'Tous les utilisateurs', + allStatuses: 'Tous les statuts', + cancelled: 'Annulé', + skipped: 'Ignoré', + dateFrom: 'Du', + dateTo: 'Au', + noEntries: 'Aucune entrée de journal trouvée', + showing: '{{count}} sur {{total}} entrées', + rowsPerPage: 'Lignes', + page: 'Page', + prev: 'Préc.', + next: 'Suiv.', + clearLog: 'Effacer le journal', + clearLogTitle: 'Effacer le journal d\'impression', + clearLogConfirm: 'Toutes les entrées du journal d\'impression seront supprimées définitivement. Les archives et les éléments de file d\'attente ne sont pas affectés. Cette action est irréversible. Êtes-vous sûr ?', + clearLogButton: 'Tout effacer', + cleared: '{{count}} entrées de journal effacées', + clearFailed: 'Échec de l\'effacement du journal d\'impression', + }, }, // Queue page diff --git a/frontend/src/i18n/locales/it.ts b/frontend/src/i18n/locales/it.ts index 7342faa94..22f3ed522 100644 --- a/frontend/src/i18n/locales/it.ts +++ b/frontend/src/i18n/locales/it.ts @@ -475,6 +475,7 @@ export default { gridView: 'Vista griglia', listView: 'Vista elenco', calendarView: 'Vista calendario', + logView: 'Registro stampe', manageTags: 'Gestisci tag', showFailedPrints: 'Mostra stampe fallite', hideFailedPrints: 'Nascondi stampe fallite', @@ -663,6 +664,34 @@ export default { actions: 'Azioni', hasTimelapse: 'Ha timelapse', }, + log: { + date: 'Data', + printName: 'Nome stampa', + printer: 'Stampante', + user: 'Utente', + status: 'Stato', + duration: 'Durata', + filament: 'Filamento', + allPrinters: 'Tutte le stampanti', + allUsers: 'Tutti gli utenti', + allStatuses: 'Tutti gli stati', + cancelled: 'Annullato', + skipped: 'Saltato', + dateFrom: 'Dal', + dateTo: 'Al', + noEntries: 'Nessuna voce di registro trovata', + showing: '{{count}} di {{total}} voci', + rowsPerPage: 'Righe', + page: 'Pagina', + prev: 'Prec.', + next: 'Succ.', + clearLog: 'Cancella registro', + clearLogTitle: 'Cancella registro stampe', + clearLogConfirm: 'Tutte le voci del registro di stampa verranno eliminate permanentemente. Gli archivi e gli elementi della coda non sono interessati. Questa azione non può essere annullata. Sei sicuro?', + clearLogButton: 'Cancella tutto', + cleared: '{{count}} voci di registro cancellate', + clearFailed: 'Impossibile cancellare il registro stampe', + }, }, // Queue page diff --git a/frontend/src/i18n/locales/ja.ts b/frontend/src/i18n/locales/ja.ts index 57e64184f..d0677f6aa 100644 --- a/frontend/src/i18n/locales/ja.ts +++ b/frontend/src/i18n/locales/ja.ts @@ -484,6 +484,7 @@ export default { gridView: 'グリッド表示', listView: 'リスト表示', calendarView: 'カレンダー表示', + logView: '印刷ログ', showFailedPrints: '失敗した印刷を表示', hideFailedPrints: '失敗した印刷を非表示', printTime: '印刷時間', @@ -677,6 +678,34 @@ export default { date: '日付', actions: '操作', }, + log: { + date: '日時', + printName: '印刷名', + printer: 'プリンター', + user: 'ユーザー', + status: 'ステータス', + duration: '所要時間', + filament: 'フィラメント', + allPrinters: '全プリンター', + allUsers: '全ユーザー', + allStatuses: '全ステータス', + cancelled: 'キャンセル', + skipped: 'スキップ', + dateFrom: '開始日', + dateTo: '終了日', + noEntries: '印刷ログが見つかりません', + showing: '{{total}}件中{{count}}件を表示', + rowsPerPage: '行数', + page: 'ページ', + prev: '前へ', + next: '次へ', + clearLog: 'ログをクリア', + clearLogTitle: '印刷ログをクリア', + clearLogConfirm: 'すべての印刷ログエントリが完全に削除されます。アーカイブとキューアイテムには影響しません。この操作は元に戻せません。よろしいですか?', + clearLogButton: 'すべてクリア', + cleared: '{{count}}件のログエントリを削除しました', + clearFailed: '印刷ログの削除に失敗しました', + }, noPrinterAvailable: '利用可能なプリンターがありません', archiveOrReprint: 'アーカイブまたは再印刷', multiPrinterPrint: 'マルチプリンター印刷', diff --git a/frontend/src/pages/ArchivesPage.tsx b/frontend/src/pages/ArchivesPage.tsx index 35b4a47fd..de00a1e38 100644 --- a/frontend/src/pages/ArchivesPage.tsx +++ b/frontend/src/pages/ArchivesPage.tsx @@ -46,6 +46,7 @@ import { ChevronRight, Settings, User, + ClipboardList, } from 'lucide-react'; import { api } from '../api/client'; import { openInSlicer, type SlicerType } from '../utils/slicer'; @@ -2064,7 +2065,7 @@ function ArchiveListRow({ } type SortOption = 'date-desc' | 'date-asc' | 'name-asc' | 'name-desc' | 'size-desc' | 'size-asc'; -type ViewMode = 'grid' | 'list' | 'calendar'; +type ViewMode = 'grid' | 'list' | 'calendar' | 'log'; type Collection = 'all' | 'recent' | 'this-week' | 'this-month' | 'favorites' | 'failed' | 'duplicates'; const collections: { id: Collection; label: string; icon: React.ReactNode }[] = [ @@ -2133,6 +2134,29 @@ export function ArchivesPage() { const [showTagManagement, setShowTagManagement] = useState(false); const [highlightedArchiveId, setHighlightedArchiveId] = useState(null); + // Log view state + const [logFilterUser, setLogFilterUser] = useState(() => + localStorage.getItem('logFilterUser') || null + ); + const [logFilterStatus, setLogFilterStatus] = useState(() => + localStorage.getItem('logFilterStatus') + ); + const [logFilterDateFrom, setLogFilterDateFrom] = useState(() => + localStorage.getItem('logFilterDateFrom') || '' + ); + const [logFilterDateTo, setLogFilterDateTo] = useState(() => + localStorage.getItem('logFilterDateTo') || '' + ); + const [logOffset, setLogOffset] = useState(() => { + const saved = localStorage.getItem('logOffset'); + return saved ? Number(saved) : 0; + }); + const [showClearLogConfirm, setShowClearLogConfirm] = useState(false); + const [logPageSize, setLogPageSize] = useState(() => { + const saved = localStorage.getItem('logPageSize'); + return saved ? Number(saved) : 25; + }); + // Clear highlight after 5 seconds and scroll to highlighted element useEffect(() => { if (highlightedArchiveId) { @@ -2173,6 +2197,27 @@ export function ArchivesPage() { queryFn: api.getSettings, }); + const { data: users } = useQuery({ + queryKey: ['users'], + queryFn: api.getUsers, + enabled: viewMode === 'log', + }); + + const { data: printLogData, isLoading: isLogLoading } = useQuery({ + queryKey: ['print-log', filterPrinter, logFilterUser, logFilterStatus, logFilterDateFrom, logFilterDateTo, search, logOffset, logPageSize], + queryFn: () => api.getPrintLog({ + search: search || undefined, + printerId: filterPrinter || undefined, + username: logFilterUser || undefined, + status: logFilterStatus || undefined, + dateFrom: logFilterDateFrom || undefined, + dateTo: logFilterDateTo || undefined, + limit: logPageSize, + offset: logOffset, + }), + enabled: viewMode === 'log', + }); + const timeFormat: TimeFormat = settings?.time_format || 'system'; const preferredSlicer: SlicerType = settings?.preferred_slicer || 'bambu_studio'; @@ -2191,6 +2236,18 @@ export function ArchivesPage() { }, }); + const clearLogMutation = useMutation({ + mutationFn: () => api.clearPrintLog(), + onSuccess: (data) => { + queryClient.invalidateQueries({ queryKey: ['print-log'] }); + setLogOffset(0); + showToast(t('archives.log.cleared', { count: data.deleted })); + }, + onError: () => { + showToast(t('archives.log.clearFailed'), 'error'); + }, + }); + // Persist all filters to localStorage useEffect(() => { if (filterPrinter !== null) { @@ -2248,6 +2305,47 @@ export function ArchivesPage() { localStorage.setItem('archiveCollection', collection); }, [collection]); + // Persist log view filters + useEffect(() => { + if (logFilterUser) { + localStorage.setItem('logFilterUser', logFilterUser); + } else { + localStorage.removeItem('logFilterUser'); + } + }, [logFilterUser]); + + useEffect(() => { + if (logFilterStatus) { + localStorage.setItem('logFilterStatus', logFilterStatus); + } else { + localStorage.removeItem('logFilterStatus'); + } + }, [logFilterStatus]); + + useEffect(() => { + if (logFilterDateFrom) { + localStorage.setItem('logFilterDateFrom', logFilterDateFrom); + } else { + localStorage.removeItem('logFilterDateFrom'); + } + }, [logFilterDateFrom]); + + useEffect(() => { + if (logFilterDateTo) { + localStorage.setItem('logFilterDateTo', logFilterDateTo); + } else { + localStorage.removeItem('logFilterDateTo'); + } + }, [logFilterDateTo]); + + useEffect(() => { + localStorage.setItem('logOffset', logOffset.toString()); + }, [logOffset]); + + useEffect(() => { + localStorage.setItem('logPageSize', logPageSize.toString()); + }, [logPageSize]); + const printerMap = new Map(printers?.map((p) => [p.id, p.name]) || []); // Extract unique materials and colors from archives @@ -2672,8 +2770,40 @@ export function ArchivesPage() { - {/* Filters */} - + {/* View mode toggle — always visible */} +
+ + + + +
+ + {/* Filters (hidden in log view which has its own filters) */} + {viewMode !== 'log' &&
{/* Search - full width on mobile */} @@ -2799,29 +2929,6 @@ export function ArchivesPage() {
-
- - - -
{hasTopFilters && ( + + +
+
+ + {/* Log table */} + + {isLogLoading ? ( +
+ +
+ ) : !printLogData?.items.length ? ( +
+ {t('archives.log.noEntries')} +
+ ) : ( + <> +
+ + + + + + + + + + + + + + {printLogData.items.map((entry) => ( + + + + + + + + + + ))} + +
{t('archives.log.date')}{t('archives.log.printName')}{t('archives.log.printer')}{t('archives.log.user')}{t('archives.log.status')}{t('archives.log.duration')}{t('archives.log.filament')}
+ {formatDateTime(entry.started_at || entry.created_at, timeFormat)} + +
+ {entry.thumbnail_path && ( + { (e.target as HTMLImageElement).style.display = 'none'; }} + /> + )} + + {entry.print_name || '—'} + +
+
{entry.printer_name || '—'}{entry.created_by_username || '—'} + + {entry.status} + + + {entry.duration_seconds ? formatDuration(entry.duration_seconds) : '—'} + +
+ {entry.filament_color && ( + + )} + + {entry.filament_type || '—'} + +
+
+
+ {/* Pagination */} +
+
+ + {t('archives.log.showing', { count: Math.min(logOffset + logPageSize, printLogData.total), total: printLogData.total })} + +
+ + +
+
+
+ + {t('archives.log.page')} {Math.floor(logOffset / logPageSize) + 1} / {Math.max(1, Math.ceil(printLogData.total / logPageSize))} + + + +
+
+ + )} +
+ + ) : null} {/* Upload Modal */} @@ -3019,6 +3331,21 @@ export function ArchivesPage() { {showTagManagement && ( setShowTagManagement(false)} /> )} + + {/* Clear Log Confirmation */} + {showClearLogConfirm && ( + { + clearLogMutation.mutate(); + setShowClearLogConfirm(false); + }} + onCancel={() => setShowClearLogConfirm(false)} + /> + )} ); } diff --git a/static/assets/index-BwlOtO_N.js b/static/assets/index-BpibLMBb.js similarity index 67% rename from static/assets/index-BwlOtO_N.js rename to static/assets/index-BpibLMBb.js index e8661984a..ac5f7d56d 100644 --- a/static/assets/index-BwlOtO_N.js +++ b/static/assets/index-BpibLMBb.js @@ -1,18 +1,18 @@ -function Aoe(t,e){for(var n=0;nr[i]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))r(i);new MutationObserver(i=>{for(const s of i)if(s.type==="childList")for(const o of s.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&r(o)}).observe(document,{childList:!0,subtree:!0});function n(i){const s={};return i.integrity&&(s.integrity=i.integrity),i.referrerPolicy&&(s.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?s.credentials="include":i.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function r(i){if(i.ep)return;i.ep=!0;const s=n(i);fetch(i.href,s)}})();var i_=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function ec(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var jT={exports:{}},Yx={};var zU;function Toe(){if(zU)return Yx;zU=1;var t=Symbol.for("react.transitional.element"),e=Symbol.for("react.fragment");function n(r,i,s){var o=null;if(s!==void 0&&(o=""+s),i.key!==void 0&&(o=""+i.key),"key"in i){s={};for(var l in i)l!=="key"&&(s[l]=i[l])}else s=i;return i=s.ref,{$$typeof:t,type:r,key:o,ref:i!==void 0?i:null,props:s}}return Yx.Fragment=e,Yx.jsx=n,Yx.jsxs=n,Yx}var UU;function Eoe(){return UU||(UU=1,jT.exports=Toe()),jT.exports}var a=Eoe(),DT={exports:{}},kn={};var BU;function Poe(){if(BU)return kn;BU=1;var t=Symbol.for("react.transitional.element"),e=Symbol.for("react.portal"),n=Symbol.for("react.fragment"),r=Symbol.for("react.strict_mode"),i=Symbol.for("react.profiler"),s=Symbol.for("react.consumer"),o=Symbol.for("react.context"),l=Symbol.for("react.forward_ref"),c=Symbol.for("react.suspense"),u=Symbol.for("react.memo"),d=Symbol.for("react.lazy"),h=Symbol.for("react.activity"),f=Symbol.iterator;function p(V){return V===null||typeof V!="object"?null:(V=f&&V[f]||V["@@iterator"],typeof V=="function"?V:null)}var x={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},v=Object.assign,b={};function y(V,X,ne){this.props=V,this.context=X,this.refs=b,this.updater=ne||x}y.prototype.isReactComponent={},y.prototype.setState=function(V,X){if(typeof V!="object"&&typeof V!="function"&&V!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,V,X,"setState")},y.prototype.forceUpdate=function(V){this.updater.enqueueForceUpdate(this,V,"forceUpdate")};function S(){}S.prototype=y.prototype;function N(V,X,ne){this.props=V,this.context=X,this.refs=b,this.updater=ne||x}var M=N.prototype=new S;M.constructor=N,v(M,y.prototype),M.isPureReactComponent=!0;var k=Array.isArray;function T(){}var C={H:null,A:null,T:null,S:null},j=Object.prototype.hasOwnProperty;function E(V,X,ne){var te=ne.ref;return{$$typeof:t,type:V,key:X,ref:te!==void 0?te:null,props:ne}}function P(V,X){return E(V.type,X,V.props)}function U(V){return typeof V=="object"&&V!==null&&V.$$typeof===t}function L(V){var X={"=":"=0",":":"=2"};return"$"+V.replace(/[=:]/g,function(ne){return X[ne]})}var B=/\/+/g;function D(V,X){return typeof V=="object"&&V!==null&&V.key!=null?L(""+V.key):X.toString(36)}function H(V){switch(V.status){case"fulfilled":return V.value;case"rejected":throw V.reason;default:switch(typeof V.status=="string"?V.then(T,T):(V.status="pending",V.then(function(X){V.status==="pending"&&(V.status="fulfilled",V.value=X)},function(X){V.status==="pending"&&(V.status="rejected",V.reason=X)})),V.status){case"fulfilled":return V.value;case"rejected":throw V.reason}}throw V}function G(V,X,ne,te,_e){var me=typeof V;(me==="undefined"||me==="boolean")&&(V=null);var he=!1;if(V===null)he=!0;else switch(me){case"bigint":case"string":case"number":he=!0;break;case"object":switch(V.$$typeof){case t:case e:he=!0;break;case d:return he=V._init,G(he(V._payload),X,ne,te,_e)}}if(he)return _e=_e(V),he=te===""?"."+D(V,0):te,k(_e)?(ne="",he!=null&&(ne=he.replace(B,"$&/")+"/"),G(_e,X,ne,"",function(le){return le})):_e!=null&&(U(_e)&&(_e=P(_e,ne+(_e.key==null||V&&V.key===_e.key?"":(""+_e.key).replace(B,"$&/")+"/")+he)),X.push(_e)),1;he=0;var Re=te===""?".":te+":";if(k(V))for(var ue=0;ue>>1,ie=G[Z];if(0>>1;Zi(ne,W))tei(_e,ne)?(G[Z]=_e,G[te]=W,Z=te):(G[Z]=ne,G[X]=W,Z=X);else if(tei(_e,W))G[Z]=_e,G[te]=W,Z=te;else break e}}return I}function i(G,I){var W=G.sortIndex-I.sortIndex;return W!==0?W:G.id-I.id}if(t.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var s=performance;t.unstable_now=function(){return s.now()}}else{var o=Date,l=o.now();t.unstable_now=function(){return o.now()-l}}var c=[],u=[],d=1,h=null,f=3,p=!1,x=!1,v=!1,b=!1,y=typeof setTimeout=="function"?setTimeout:null,S=typeof clearTimeout=="function"?clearTimeout:null,N=typeof setImmediate<"u"?setImmediate:null;function M(G){for(var I=n(u);I!==null;){if(I.callback===null)r(u);else if(I.startTime<=G)r(u),I.sortIndex=I.expirationTime,e(c,I);else break;I=n(u)}}function k(G){if(v=!1,M(G),!x)if(n(c)!==null)x=!0,T||(T=!0,L());else{var I=n(u);I!==null&&H(k,I.startTime-G)}}var T=!1,C=-1,j=5,E=-1;function P(){return b?!0:!(t.unstable_now()-EG&&P());){var Z=h.callback;if(typeof Z=="function"){h.callback=null,f=h.priorityLevel;var ie=Z(h.expirationTime<=G);if(G=t.unstable_now(),typeof ie=="function"){h.callback=ie,M(G),I=!0;break t}h===n(c)&&r(c),M(G)}else r(c);h=n(c)}if(h!==null)I=!0;else{var V=n(u);V!==null&&H(k,V.startTime-G),I=!1}}break e}finally{h=null,f=W,p=!1}I=void 0}}finally{I?L():T=!1}}}var L;if(typeof N=="function")L=function(){N(U)};else if(typeof MessageChannel<"u"){var B=new MessageChannel,D=B.port2;B.port1.onmessage=U,L=function(){D.postMessage(null)}}else L=function(){y(U,0)};function H(G,I){C=y(function(){G(t.unstable_now())},I)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(G){G.callback=null},t.unstable_forceFrameRate=function(G){0>G||125Z?(G.sortIndex=W,e(u,G),n(c)===null&&G===n(u)&&(v?(S(C),C=-1):v=!0,H(k,W-Z))):(G.sortIndex=ie,e(c,G),x||p||(x=!0,T||(T=!0,L()))),G},t.unstable_shouldYield=P,t.unstable_wrapCallback=function(G){var I=f;return function(){var W=f;f=I;try{return G.apply(this,arguments)}finally{f=W}}}})(LT)),LT}var VU;function Roe(){return VU||(VU=1,FT.exports=Doe()),FT.exports}var OT={exports:{}},ls={};var GU;function Foe(){if(GU)return ls;GU=1;var t=Ib();function e(c){var u="https://react.dev/errors/"+c;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(e){console.error(e)}}return t(),OT.exports=Foe(),OT.exports}var WU;function Loe(){if(WU)return Qx;WU=1;var t=Roe(),e=Ib(),n=lK();function r(m){var g="https://react.dev/errors/"+m;if(1ie||(m.current=Z[ie],Z[ie]=null,ie--)}function ne(m,g){ie++,Z[ie]=m.current,m.current=g}var te=V(null),_e=V(null),me=V(null),he=V(null);function Re(m,g){switch(ne(me,g),ne(_e,m),ne(te,null),g.nodeType){case 9:case 11:m=(m=g.documentElement)&&(m=m.namespaceURI)?lU(m):0;break;default:if(m=g.tagName,g=g.namespaceURI)g=lU(g),m=cU(g,m);else switch(m){case"svg":m=1;break;case"math":m=2;break;default:m=0}}X(te),ne(te,m)}function ue(){X(te),X(_e),X(me)}function le(m){m.memoizedState!==null&&ne(he,m);var g=te.current,_=cU(g,m.type);g!==_&&(ne(_e,m),ne(te,_))}function Ne(m){_e.current===m&&(X(te),X(_e)),he.current===m&&(X(he),qx._currentValue=W)}var ee,Le;function $(m){if(ee===void 0)try{throw Error()}catch(_){var g=_.stack.trim().match(/\n( *(at )?)/);ee=g&&g[1]||"",Le=-1<_.stack.indexOf(` +function Aoe(t,e){for(var n=0;nr[i]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))r(i);new MutationObserver(i=>{for(const s of i)if(s.type==="childList")for(const o of s.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&r(o)}).observe(document,{childList:!0,subtree:!0});function n(i){const s={};return i.integrity&&(s.integrity=i.integrity),i.referrerPolicy&&(s.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?s.credentials="include":i.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function r(i){if(i.ep)return;i.ep=!0;const s=n(i);fetch(i.href,s)}})();var i_=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function tc(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var jT={exports:{}},Qx={};var zU;function Toe(){if(zU)return Qx;zU=1;var t=Symbol.for("react.transitional.element"),e=Symbol.for("react.fragment");function n(r,i,s){var o=null;if(s!==void 0&&(o=""+s),i.key!==void 0&&(o=""+i.key),"key"in i){s={};for(var l in i)l!=="key"&&(s[l]=i[l])}else s=i;return i=s.ref,{$$typeof:t,type:r,key:o,ref:i!==void 0?i:null,props:s}}return Qx.Fragment=e,Qx.jsx=n,Qx.jsxs=n,Qx}var UU;function Eoe(){return UU||(UU=1,jT.exports=Toe()),jT.exports}var a=Eoe(),DT={exports:{}},Cn={};var BU;function Poe(){if(BU)return Cn;BU=1;var t=Symbol.for("react.transitional.element"),e=Symbol.for("react.portal"),n=Symbol.for("react.fragment"),r=Symbol.for("react.strict_mode"),i=Symbol.for("react.profiler"),s=Symbol.for("react.consumer"),o=Symbol.for("react.context"),l=Symbol.for("react.forward_ref"),c=Symbol.for("react.suspense"),u=Symbol.for("react.memo"),d=Symbol.for("react.lazy"),h=Symbol.for("react.activity"),f=Symbol.iterator;function p(V){return V===null||typeof V!="object"?null:(V=f&&V[f]||V["@@iterator"],typeof V=="function"?V:null)}var x={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},v=Object.assign,b={};function y(V,X,re){this.props=V,this.context=X,this.refs=b,this.updater=re||x}y.prototype.isReactComponent={},y.prototype.setState=function(V,X){if(typeof V!="object"&&typeof V!="function"&&V!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,V,X,"setState")},y.prototype.forceUpdate=function(V){this.updater.enqueueForceUpdate(this,V,"forceUpdate")};function S(){}S.prototype=y.prototype;function N(V,X,re){this.props=V,this.context=X,this.refs=b,this.updater=re||x}var M=N.prototype=new S;M.constructor=N,v(M,y.prototype),M.isPureReactComponent=!0;var C=Array.isArray;function T(){}var k={H:null,A:null,T:null,S:null},j=Object.prototype.hasOwnProperty;function E(V,X,re){var te=re.ref;return{$$typeof:t,type:V,key:X,ref:te!==void 0?te:null,props:re}}function P(V,X){return E(V.type,X,V.props)}function U(V){return typeof V=="object"&&V!==null&&V.$$typeof===t}function L(V){var X={"=":"=0",":":"=2"};return"$"+V.replace(/[=:]/g,function(re){return X[re]})}var B=/\/+/g;function D(V,X){return typeof V=="object"&&V!==null&&V.key!=null?L(""+V.key):X.toString(36)}function H(V){switch(V.status){case"fulfilled":return V.value;case"rejected":throw V.reason;default:switch(typeof V.status=="string"?V.then(T,T):(V.status="pending",V.then(function(X){V.status==="pending"&&(V.status="fulfilled",V.value=X)},function(X){V.status==="pending"&&(V.status="rejected",V.reason=X)})),V.status){case"fulfilled":return V.value;case"rejected":throw V.reason}}throw V}function G(V,X,re,te,_e){var pe=typeof V;(pe==="undefined"||pe==="boolean")&&(V=null);var me=!1;if(V===null)me=!0;else switch(pe){case"bigint":case"string":case"number":me=!0;break;case"object":switch(V.$$typeof){case t:case e:me=!0;break;case d:return me=V._init,G(me(V._payload),X,re,te,_e)}}if(me)return _e=_e(V),me=te===""?"."+D(V,0):te,C(_e)?(re="",me!=null&&(re=me.replace(B,"$&/")+"/"),G(_e,X,re,"",function(ce){return ce})):_e!=null&&(U(_e)&&(_e=P(_e,re+(_e.key==null||V&&V.key===_e.key?"":(""+_e.key).replace(B,"$&/")+"/")+me)),X.push(_e)),1;me=0;var De=te===""?".":te+":";if(C(V))for(var de=0;de>>1,ae=G[Z];if(0>>1;Zi(re,W))tei(_e,re)?(G[Z]=_e,G[te]=W,Z=te):(G[Z]=re,G[X]=W,Z=X);else if(tei(_e,W))G[Z]=_e,G[te]=W,Z=te;else break e}}return I}function i(G,I){var W=G.sortIndex-I.sortIndex;return W!==0?W:G.id-I.id}if(t.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var s=performance;t.unstable_now=function(){return s.now()}}else{var o=Date,l=o.now();t.unstable_now=function(){return o.now()-l}}var c=[],u=[],d=1,h=null,f=3,p=!1,x=!1,v=!1,b=!1,y=typeof setTimeout=="function"?setTimeout:null,S=typeof clearTimeout=="function"?clearTimeout:null,N=typeof setImmediate<"u"?setImmediate:null;function M(G){for(var I=n(u);I!==null;){if(I.callback===null)r(u);else if(I.startTime<=G)r(u),I.sortIndex=I.expirationTime,e(c,I);else break;I=n(u)}}function C(G){if(v=!1,M(G),!x)if(n(c)!==null)x=!0,T||(T=!0,L());else{var I=n(u);I!==null&&H(C,I.startTime-G)}}var T=!1,k=-1,j=5,E=-1;function P(){return b?!0:!(t.unstable_now()-EG&&P());){var Z=h.callback;if(typeof Z=="function"){h.callback=null,f=h.priorityLevel;var ae=Z(h.expirationTime<=G);if(G=t.unstable_now(),typeof ae=="function"){h.callback=ae,M(G),I=!0;break t}h===n(c)&&r(c),M(G)}else r(c);h=n(c)}if(h!==null)I=!0;else{var V=n(u);V!==null&&H(C,V.startTime-G),I=!1}}break e}finally{h=null,f=W,p=!1}I=void 0}}finally{I?L():T=!1}}}var L;if(typeof N=="function")L=function(){N(U)};else if(typeof MessageChannel<"u"){var B=new MessageChannel,D=B.port2;B.port1.onmessage=U,L=function(){D.postMessage(null)}}else L=function(){y(U,0)};function H(G,I){k=y(function(){G(t.unstable_now())},I)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(G){G.callback=null},t.unstable_forceFrameRate=function(G){0>G||125Z?(G.sortIndex=W,e(u,G),n(c)===null&&G===n(u)&&(v?(S(k),k=-1):v=!0,H(C,W-Z))):(G.sortIndex=ae,e(c,G),x||p||(x=!0,T||(T=!0,L()))),G},t.unstable_shouldYield=P,t.unstable_wrapCallback=function(G){var I=f;return function(){var W=f;f=I;try{return G.apply(this,arguments)}finally{f=W}}}})(LT)),LT}var VU;function Roe(){return VU||(VU=1,FT.exports=Doe()),FT.exports}var OT={exports:{}},ls={};var GU;function Foe(){if(GU)return ls;GU=1;var t=zb();function e(c){var u="https://react.dev/errors/"+c;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(e){console.error(e)}}return t(),OT.exports=Foe(),OT.exports}var WU;function Loe(){if(WU)return Zx;WU=1;var t=Roe(),e=zb(),n=lK();function r(m){var g="https://react.dev/errors/"+m;if(1ae||(m.current=Z[ae],Z[ae]=null,ae--)}function re(m,g){ae++,Z[ae]=m.current,m.current=g}var te=V(null),_e=V(null),pe=V(null),me=V(null);function De(m,g){switch(re(pe,g),re(_e,m),re(te,null),g.nodeType){case 9:case 11:m=(m=g.documentElement)&&(m=m.namespaceURI)?lU(m):0;break;default:if(m=g.tagName,g=g.namespaceURI)g=lU(g),m=cU(g,m);else switch(m){case"svg":m=1;break;case"math":m=2;break;default:m=0}}X(te),re(te,m)}function de(){X(te),X(_e),X(pe)}function ce(m){m.memoizedState!==null&&re(me,m);var g=te.current,_=cU(g,m.type);g!==_&&(re(_e,m),re(te,_))}function ke(m){_e.current===m&&(X(te),X(_e)),me.current===m&&(X(me),Wx._currentValue=W)}var ee,Le;function $(m){if(ee===void 0)try{throw Error()}catch(_){var g=_.stack.trim().match(/\n( *(at )?)/);ee=g&&g[1]||"",Le=-1<_.stack.indexOf(` at`)?" ()":-1<_.stack.indexOf("@")?"@unknown:0:0":""}return` -`+ee+m+Le}var K=!1;function ce(m,g){if(!m||K)return"";K=!0;var _=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{var A={DetermineComponentFrameRoot:function(){try{if(g){var kt=function(){throw Error()};if(Object.defineProperty(kt.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(kt,[])}catch(xt){var mt=xt}Reflect.construct(m,[],kt)}else{try{kt.call()}catch(xt){mt=xt}m.call(kt.prototype)}}else{try{throw Error()}catch(xt){mt=xt}(kt=m())&&typeof kt.catch=="function"&&kt.catch(function(){})}}catch(xt){if(xt&&mt&&typeof xt.stack=="string")return[xt.stack,mt.stack]}return[null,null]}};A.DetermineComponentFrameRoot.displayName="DetermineComponentFrameRoot";var R=Object.getOwnPropertyDescriptor(A.DetermineComponentFrameRoot,"name");R&&R.configurable&&Object.defineProperty(A.DetermineComponentFrameRoot,"name",{value:"DetermineComponentFrameRoot"});var O=A.DetermineComponentFrameRoot(),re=O[0],ke=O[1];if(re&&ke){var Be=re.split(` -`),ut=ke.split(` -`);for(R=A=0;AR||Be[A]!==ut[R]){var wt=` -`+Be[A].replace(" at new "," at ");return m.displayName&&wt.includes("")&&(wt=wt.replace("",m.displayName)),wt}while(1<=A&&0<=R);break}}}finally{K=!1,Error.prepareStackTrace=_}return(_=m?m.displayName||m.name:"")?$(_):""}function Q(m,g){switch(m.tag){case 26:case 27:case 5:return $(m.type);case 16:return $("Lazy");case 13:return m.child!==g&&g!==null?$("Suspense Fallback"):$("Suspense");case 19:return $("SuspenseList");case 0:case 15:return ce(m.type,!1);case 11:return ce(m.type.render,!1);case 1:return ce(m.type,!0);case 31:return $("Activity");default:return""}}function se(m){try{var g="",_=null;do g+=Q(m,_),_=m,m=m.return;while(m);return g}catch(A){return` +`+ee+m+Le}var K=!1;function ue(m,g){if(!m||K)return"";K=!0;var _=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{var A={DetermineComponentFrameRoot:function(){try{if(g){var Ct=function(){throw Error()};if(Object.defineProperty(Ct.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(Ct,[])}catch(xt){var mt=xt}Reflect.construct(m,[],Ct)}else{try{Ct.call()}catch(xt){mt=xt}m.call(Ct.prototype)}}else{try{throw Error()}catch(xt){mt=xt}(Ct=m())&&typeof Ct.catch=="function"&&Ct.catch(function(){})}}catch(xt){if(xt&&mt&&typeof xt.stack=="string")return[xt.stack,mt.stack]}return[null,null]}};A.DetermineComponentFrameRoot.displayName="DetermineComponentFrameRoot";var F=Object.getOwnPropertyDescriptor(A.DetermineComponentFrameRoot,"name");F&&F.configurable&&Object.defineProperty(A.DetermineComponentFrameRoot,"name",{value:"DetermineComponentFrameRoot"});var O=A.DetermineComponentFrameRoot(),ie=O[0],Me=O[1];if(ie&&Me){var Be=ie.split(` +`),dt=Me.split(` +`);for(F=A=0;AF||Be[A]!==dt[F]){var vt=` +`+Be[A].replace(" at new "," at ");return m.displayName&&vt.includes("")&&(vt=vt.replace("",m.displayName)),vt}while(1<=A&&0<=F);break}}}finally{K=!1,Error.prepareStackTrace=_}return(_=m?m.displayName||m.name:"")?$(_):""}function Q(m,g){switch(m.tag){case 26:case 27:case 5:return $(m.type);case 16:return $("Lazy");case 13:return m.child!==g&&g!==null?$("Suspense Fallback"):$("Suspense");case 19:return $("SuspenseList");case 0:case 15:return ue(m.type,!1);case 11:return ue(m.type.render,!1);case 1:return ue(m.type,!0);case 31:return $("Activity");default:return""}}function oe(m){try{var g="",_=null;do g+=Q(m,_),_=m,m=m.return;while(m);return g}catch(A){return` Error generating stack: `+A.message+` -`+A.stack}}var Y=Object.prototype.hasOwnProperty,de=t.unstable_scheduleCallback,pe=t.unstable_cancelCallback,J=t.unstable_shouldYield,z=t.unstable_requestPaint,F=t.unstable_now,q=t.unstable_getCurrentPriorityLevel,fe=t.unstable_ImmediatePriority,we=t.unstable_UserBlockingPriority,xe=t.unstable_NormalPriority,He=t.unstable_LowPriority,Se=t.unstable_IdlePriority,$e=t.log,Qe=t.unstable_setDisableYieldValue,ye=null,ve=null;function Ce(m){if(typeof $e=="function"&&Qe(m),ve&&typeof ve.setStrictMode=="function")try{ve.setStrictMode(ye,m)}catch{}}var Ue=Math.clz32?Math.clz32:Ae,je=Math.log,Ve=Math.LN2;function Ae(m){return m>>>=0,m===0?32:31-(je(m)/Ve|0)|0}var Ze=256,Pe=262144,Xe=4194304;function Fe(m){var g=m&42;if(g!==0)return g;switch(m&-m){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 m&261888;case 262144:case 524288:case 1048576:case 2097152:return m&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return m&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return m}}function Oe(m,g,_){var A=m.pendingLanes;if(A===0)return 0;var R=0,O=m.suspendedLanes,re=m.pingedLanes;m=m.warmLanes;var ke=A&134217727;return ke!==0?(A=ke&~O,A!==0?R=Fe(A):(re&=ke,re!==0?R=Fe(re):_||(_=ke&~m,_!==0&&(R=Fe(_))))):(ke=A&~O,ke!==0?R=Fe(ke):re!==0?R=Fe(re):_||(_=A&~m,_!==0&&(R=Fe(_)))),R===0?0:g!==0&&g!==R&&(g&O)===0&&(O=R&-R,_=g&-g,O>=_||O===32&&(_&4194048)!==0)?g:R}function Me(m,g){return(m.pendingLanes&~(m.suspendedLanes&~m.pingedLanes)&g)===0}function Je(m,g){switch(m){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 yt(){var m=Xe;return Xe<<=1,(Xe&62914560)===0&&(Xe=4194304),m}function Mt(m){for(var g=[],_=0;31>_;_++)g.push(m);return g}function an(m,g){m.pendingLanes|=g,g!==268435456&&(m.suspendedLanes=0,m.pingedLanes=0,m.warmLanes=0)}function Pt(m,g,_,A,R,O){var re=m.pendingLanes;m.pendingLanes=_,m.suspendedLanes=0,m.pingedLanes=0,m.warmLanes=0,m.expiredLanes&=_,m.entangledLanes&=_,m.errorRecoveryDisabledLanes&=_,m.shellSuspendCounter=0;var ke=m.entanglements,Be=m.expirationTimes,ut=m.hiddenUpdates;for(_=re&~_;0<_;){var wt=31-Ue(_),kt=1<"u")return null;try{return m.activeElement||m.body}catch{return m.body}}var qr=/[\n"\\]/g;function Dn(m){return m.replace(qr,function(g){return"\\"+g.charCodeAt(0).toString(16)+" "})}function _n(m,g,_,A,R,O,re,ke){m.name="",re!=null&&typeof re!="function"&&typeof re!="symbol"&&typeof re!="boolean"?m.type=re:m.removeAttribute("type"),g!=null?re==="number"?(g===0&&m.value===""||m.value!=g)&&(m.value=""+Tn(g)):m.value!==""+Tn(g)&&(m.value=""+Tn(g)):re!=="submit"&&re!=="reset"||m.removeAttribute("value"),g!=null?hi(m,re,Tn(g)):_!=null?hi(m,re,Tn(_)):A!=null&&m.removeAttribute("value"),R==null&&O!=null&&(m.defaultChecked=!!O),R!=null&&(m.checked=R&&typeof R!="function"&&typeof R!="symbol"),ke!=null&&typeof ke!="function"&&typeof ke!="symbol"&&typeof ke!="boolean"?m.name=""+Tn(ke):m.removeAttribute("name")}function Gn(m,g,_,A,R,O,re,ke){if(O!=null&&typeof O!="function"&&typeof O!="symbol"&&typeof O!="boolean"&&(m.type=O),g!=null||_!=null){if(!(O!=="submit"&&O!=="reset"||g!=null)){fn(m);return}_=_!=null?""+Tn(_):"",g=g!=null?""+Tn(g):_,ke||g===m.value||(m.value=g),m.defaultValue=g}A=A??R,A=typeof A!="function"&&typeof A!="symbol"&&!!A,m.checked=ke?m.checked:!!A,m.defaultChecked=!!A,re!=null&&typeof re!="function"&&typeof re!="symbol"&&typeof re!="boolean"&&(m.name=re),fn(m)}function hi(m,g,_){g==="number"&&Gr(m.ownerDocument)===m||m.defaultValue===""+_||(m.defaultValue=""+_)}function mr(m,g,_,A){if(m=m.options,g){g={};for(var R=0;R<_.length;R++)g["$"+_[R]]=!0;for(_=0;_"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),Or=!1;if(Li)try{var Cl={};Object.defineProperty(Cl,"passive",{get:function(){Or=!0}}),window.addEventListener("test",Cl,Cl),window.removeEventListener("test",Cl,Cl)}catch{Or=!1}var Ba=null,wi=null,ic=null;function Wr(){if(ic)return ic;var m,g=wi,_=g.length,A,R="value"in Ba?Ba.value:Ba.textContent,O=R.length;for(m=0;m<_&&g[m]===R[m];m++);var re=_-m;for(A=1;A<=re&&g[_-A]===R[O-A];A++);return ic=R.slice(m,1=mx),pI=" ",gI=!1;function bI(m,g){switch(m){case"keyup":return Yae.indexOf(g.keyCode)!==-1;case"keydown":return g.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function xI(m){return m=m.detail,typeof m=="object"&&"data"in m?m.data:null}var up=!1;function Zae(m,g){switch(m){case"compositionend":return xI(g);case"keypress":return g.which!==32?null:(gI=!0,pI);case"textInput":return m=g.data,m===pI&&gI?null:m;default:return null}}function Jae(m,g){if(up)return m==="compositionend"||!IM&&bI(m,g)?(m=Wr(),ic=wi=Ba=null,up=!1,m):null;switch(m){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-m};m=A}e:{for(;_;){if(_.nextSibling){_=_.nextSibling;break e}_=_.parentNode}_=void 0}_=kI(_)}}function AI(m,g){return m&&g?m===g?!0:m&&m.nodeType===3?!1:g&&g.nodeType===3?AI(m,g.parentNode):"contains"in m?m.contains(g):m.compareDocumentPosition?!!(m.compareDocumentPosition(g)&16):!1:!1}function TI(m){m=m!=null&&m.ownerDocument!=null&&m.ownerDocument.defaultView!=null?m.ownerDocument.defaultView:window;for(var g=Gr(m.document);g instanceof m.HTMLIFrameElement;){try{var _=typeof g.contentWindow.location.href=="string"}catch{_=!1}if(_)m=g.contentWindow;else break;g=Gr(m.document)}return g}function BM(m){var g=m&&m.nodeName&&m.nodeName.toLowerCase();return g&&(g==="input"&&(m.type==="text"||m.type==="search"||m.type==="tel"||m.type==="url"||m.type==="password")||g==="textarea"||m.contentEditable==="true")}var ose=Li&&"documentMode"in document&&11>=document.documentMode,dp=null,HM=null,bx=null,$M=!1;function EI(m,g,_){var A=_.window===_?_.document:_.nodeType===9?_:_.ownerDocument;$M||dp==null||dp!==Gr(A)||(A=dp,"selectionStart"in A&&BM(A)?A={start:A.selectionStart,end:A.selectionEnd}:(A=(A.ownerDocument&&A.ownerDocument.defaultView||window).getSelection(),A={anchorNode:A.anchorNode,anchorOffset:A.anchorOffset,focusNode:A.focusNode,focusOffset:A.focusOffset}),bx&&gx(bx,A)||(bx=A,A=$w(HM,"onSelect"),0>=re,R-=re,sc=1<<32-Ue(g)+R|_<jn?(Zn=Yt,Yt=null):Zn=Yt.sibling;var cr=mt(tt,Yt,ct[jn],St);if(cr===null){Yt===null&&(Yt=Zn);break}m&&Yt&&cr.alternate===null&&g(tt,Yt),qe=O(cr,qe,jn),lr===null?rn=cr:lr.sibling=cr,lr=cr,Yt=Zn}if(jn===ct.length)return _(tt,Yt),tr&&Zc(tt,jn),rn;if(Yt===null){for(;jnjn?(Zn=Yt,Yt=null):Zn=Yt.sibling;var Vd=mt(tt,Yt,cr.value,St);if(Vd===null){Yt===null&&(Yt=Zn);break}m&&Yt&&Vd.alternate===null&&g(tt,Yt),qe=O(Vd,qe,jn),lr===null?rn=Vd:lr.sibling=Vd,lr=Vd,Yt=Zn}if(cr.done)return _(tt,Yt),tr&&Zc(tt,jn),rn;if(Yt===null){for(;!cr.done;jn++,cr=ct.next())cr=kt(tt,cr.value,St),cr!==null&&(qe=O(cr,qe,jn),lr===null?rn=cr:lr.sibling=cr,lr=cr);return tr&&Zc(tt,jn),rn}for(Yt=A(Yt);!cr.done;jn++,cr=ct.next())cr=xt(Yt,tt,jn,cr.value,St),cr!==null&&(m&&cr.alternate!==null&&Yt.delete(cr.key===null?jn:cr.key),qe=O(cr,qe,jn),lr===null?rn=cr:lr.sibling=cr,lr=cr);return m&&Yt.forEach(function(Moe){return g(tt,Moe)}),tr&&Zc(tt,jn),rn}function Ar(tt,qe,ct,St){if(typeof ct=="object"&&ct!==null&&ct.type===v&&ct.key===null&&(ct=ct.props.children),typeof ct=="object"&&ct!==null){switch(ct.$$typeof){case p:e:{for(var rn=ct.key;qe!==null;){if(qe.key===rn){if(rn=ct.type,rn===v){if(qe.tag===7){_(tt,qe.sibling),St=R(qe,ct.props.children),St.return=tt,tt=St;break e}}else if(qe.elementType===rn||typeof rn=="object"&&rn!==null&&rn.$$typeof===j&&Nm(rn)===qe.type){_(tt,qe.sibling),St=R(qe,ct.props),Sx(St,ct),St.return=tt,tt=St;break e}_(tt,qe);break}else g(tt,qe);qe=qe.sibling}ct.type===v?(St=ym(ct.props.children,tt.mode,St,ct.key),St.return=tt,tt=St):(St=sw(ct.type,ct.key,ct.props,null,tt.mode,St),Sx(St,ct),St.return=tt,tt=St)}return re(tt);case x:e:{for(rn=ct.key;qe!==null;){if(qe.key===rn)if(qe.tag===4&&qe.stateNode.containerInfo===ct.containerInfo&&qe.stateNode.implementation===ct.implementation){_(tt,qe.sibling),St=R(qe,ct.children||[]),St.return=tt,tt=St;break e}else{_(tt,qe);break}else g(tt,qe);qe=qe.sibling}St=YM(ct,tt.mode,St),St.return=tt,tt=St}return re(tt);case j:return ct=Nm(ct),Ar(tt,qe,ct,St)}if(H(ct))return Wt(tt,qe,ct,St);if(L(ct)){if(rn=L(ct),typeof rn!="function")throw Error(r(150));return ct=rn.call(ct),dn(tt,qe,ct,St)}if(typeof ct.then=="function")return Ar(tt,qe,mw(ct),St);if(ct.$$typeof===N)return Ar(tt,qe,cw(tt,ct),St);fw(tt,ct)}return typeof ct=="string"&&ct!==""||typeof ct=="number"||typeof ct=="bigint"?(ct=""+ct,qe!==null&&qe.tag===6?(_(tt,qe.sibling),St=R(qe,ct),St.return=tt,tt=St):(_(tt,qe),St=XM(ct,tt.mode,St),St.return=tt,tt=St),re(tt)):_(tt,qe)}return function(tt,qe,ct,St){try{_x=0;var rn=Ar(tt,qe,ct,St);return _p=null,rn}catch(Yt){if(Yt===wp||Yt===dw)throw Yt;var lr=ho(29,Yt,null,tt.mode);return lr.lanes=St,lr.return=tt,lr}}}var km=JI(!0),e5=JI(!1),Md=!1;function lA(m){m.updateQueue={baseState:m.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function cA(m,g){m=m.updateQueue,g.updateQueue===m&&(g.updateQueue={baseState:m.baseState,firstBaseUpdate:m.firstBaseUpdate,lastBaseUpdate:m.lastBaseUpdate,shared:m.shared,callbacks:null})}function Ad(m){return{lane:m,tag:0,payload:null,callback:null,next:null}}function Td(m,g,_){var A=m.updateQueue;if(A===null)return null;if(A=A.shared,(pr&2)!==0){var R=A.pending;return R===null?g.next=g:(g.next=R.next,R.next=g),A.pending=g,g=aw(m),OI(m,null,_),g}return iw(m,A,g,_),aw(m)}function Nx(m,g,_){if(g=g.updateQueue,g!==null&&(g=g.shared,(_&4194048)!==0)){var A=g.lanes;A&=m.pendingLanes,_|=A,g.lanes=_,gt(m,_)}}function uA(m,g){var _=m.updateQueue,A=m.alternate;if(A!==null&&(A=A.updateQueue,_===A)){var R=null,O=null;if(_=_.firstBaseUpdate,_!==null){do{var re={lane:_.lane,tag:_.tag,payload:_.payload,callback:null,next:null};O===null?R=O=re:O=O.next=re,_=_.next}while(_!==null);O===null?R=O=g:O=O.next=g}else R=O=g;_={baseState:A.baseState,firstBaseUpdate:R,lastBaseUpdate:O,shared:A.shared,callbacks:A.callbacks},m.updateQueue=_;return}m=_.lastBaseUpdate,m===null?_.firstBaseUpdate=g:m.next=g,_.lastBaseUpdate=g}var dA=!1;function Cx(){if(dA){var m=vp;if(m!==null)throw m}}function kx(m,g,_,A){dA=!1;var R=m.updateQueue;Md=!1;var O=R.firstBaseUpdate,re=R.lastBaseUpdate,ke=R.shared.pending;if(ke!==null){R.shared.pending=null;var Be=ke,ut=Be.next;Be.next=null,re===null?O=ut:re.next=ut,re=Be;var wt=m.alternate;wt!==null&&(wt=wt.updateQueue,ke=wt.lastBaseUpdate,ke!==re&&(ke===null?wt.firstBaseUpdate=ut:ke.next=ut,wt.lastBaseUpdate=Be))}if(O!==null){var kt=R.baseState;re=0,wt=ut=Be=null,ke=O;do{var mt=ke.lane&-536870913,xt=mt!==ke.lane;if(xt?(Qn&mt)===mt:(A&mt)===mt){mt!==0&&mt===yp&&(dA=!0),wt!==null&&(wt=wt.next={lane:0,tag:ke.tag,payload:ke.payload,callback:null,next:null});e:{var Wt=m,dn=ke;mt=g;var Ar=_;switch(dn.tag){case 1:if(Wt=dn.payload,typeof Wt=="function"){kt=Wt.call(Ar,kt,mt);break e}kt=Wt;break e;case 3:Wt.flags=Wt.flags&-65537|128;case 0:if(Wt=dn.payload,mt=typeof Wt=="function"?Wt.call(Ar,kt,mt):Wt,mt==null)break e;kt=h({},kt,mt);break e;case 2:Md=!0}}mt=ke.callback,mt!==null&&(m.flags|=64,xt&&(m.flags|=8192),xt=R.callbacks,xt===null?R.callbacks=[mt]:xt.push(mt))}else xt={lane:mt,tag:ke.tag,payload:ke.payload,callback:ke.callback,next:null},wt===null?(ut=wt=xt,Be=kt):wt=wt.next=xt,re|=mt;if(ke=ke.next,ke===null){if(ke=R.shared.pending,ke===null)break;xt=ke,ke=xt.next,xt.next=null,R.lastBaseUpdate=xt,R.shared.pending=null}}while(!0);wt===null&&(Be=kt),R.baseState=Be,R.firstBaseUpdate=ut,R.lastBaseUpdate=wt,O===null&&(R.shared.lanes=0),Rd|=re,m.lanes=re,m.memoizedState=kt}}function t5(m,g){if(typeof m!="function")throw Error(r(191,m));m.call(g)}function n5(m,g){var _=m.callbacks;if(_!==null)for(m.callbacks=null,m=0;m<_.length;m++)t5(_[m],g)}var Sp=V(null),pw=V(0);function r5(m,g){m=cu,ne(pw,m),ne(Sp,g),cu=m|g.baseLanes}function hA(){ne(pw,cu),ne(Sp,Sp.current)}function mA(){cu=pw.current,X(Sp),X(pw)}var mo=V(null),$o=null;function Ed(m){var g=m.alternate;ne(Oi,Oi.current&1),ne(mo,m),$o===null&&(g===null||Sp.current!==null||g.memoizedState!==null)&&($o=m)}function fA(m){ne(Oi,Oi.current),ne(mo,m),$o===null&&($o=m)}function i5(m){m.tag===22?(ne(Oi,Oi.current),ne(mo,m),$o===null&&($o=m)):Pd()}function Pd(){ne(Oi,Oi.current),ne(mo,mo.current)}function fo(m){X(mo),$o===m&&($o=null),X(Oi)}var Oi=V(0);function gw(m){for(var g=m;g!==null;){if(g.tag===13){var _=g.memoizedState;if(_!==null&&(_=_.dehydrated,_===null||vT(_)||wT(_)))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===m)break;for(;g.sibling===null;){if(g.return===null||g.return===m)return null;g=g.return}g.sibling.return=g.return,g=g.sibling}return null}var tu=0,En=null,kr=null,Wi=null,bw=!1,Np=!1,Mm=!1,xw=0,Mx=0,Cp=null,bse=0;function Si(){throw Error(r(321))}function pA(m,g){if(g===null)return!1;for(var _=0;_O?O:8;var re=G.T,ke={};G.T=ke,EA(m,!1,g,_);try{var Be=R(),ut=G.S;if(ut!==null&&ut(ke,Be),Be!==null&&typeof Be=="object"&&typeof Be.then=="function"){var wt=gse(Be,A);Tx(m,g,wt,bo(m))}else Tx(m,g,A,bo(m))}catch(kt){Tx(m,g,{then:function(){},status:"rejected",reason:kt},bo())}finally{I.p=O,re!==null&&ke.types!==null&&(re.types=ke.types),G.T=re}}function _se(){}function AA(m,g,_,A){if(m.tag!==5)throw Error(r(476));var R=R5(m).queue;D5(m,R,g,W,_===null?_se:function(){return F5(m),_(A)})}function R5(m){var g=m.memoizedState;if(g!==null)return g;g={memoizedState:W,baseState:W,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:nu,lastRenderedState:W},next:null};var _={};return g.next={memoizedState:_,baseState:_,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:nu,lastRenderedState:_},next:null},m.memoizedState=g,m=m.alternate,m!==null&&(m.memoizedState=g),g}function F5(m){var g=R5(m);g.next===null&&(g=m.alternate.memoizedState),Tx(m,g.next.queue,{},bo())}function TA(){return $a(qx)}function L5(){return Ii().memoizedState}function O5(){return Ii().memoizedState}function Sse(m){for(var g=m.return;g!==null;){switch(g.tag){case 24:case 3:var _=bo();m=Ad(_);var A=Td(g,m,_);A!==null&&(qs(A,g,_),Nx(A,g,_)),g={cache:iA()},m.payload=g;return}g=g.return}}function Nse(m,g,_){var A=bo();_={lane:A,revertLane:0,gesture:null,action:_,hasEagerState:!1,eagerState:null,next:null},Nw(m)?z5(g,_):(_=WM(m,g,_,A),_!==null&&(qs(_,m,A),U5(_,g,A)))}function I5(m,g,_){var A=bo();Tx(m,g,_,A)}function Tx(m,g,_,A){var R={lane:A,revertLane:0,gesture:null,action:_,hasEagerState:!1,eagerState:null,next:null};if(Nw(m))z5(g,R);else{var O=m.alternate;if(m.lanes===0&&(O===null||O.lanes===0)&&(O=g.lastRenderedReducer,O!==null))try{var re=g.lastRenderedState,ke=O(re,_);if(R.hasEagerState=!0,R.eagerState=ke,uo(ke,re))return iw(m,g,R,0),Ir===null&&rw(),!1}catch{}if(_=WM(m,g,R,A),_!==null)return qs(_,m,A),U5(_,g,A),!0}return!1}function EA(m,g,_,A){if(A={lane:2,revertLane:lT(),gesture:null,action:A,hasEagerState:!1,eagerState:null,next:null},Nw(m)){if(g)throw Error(r(479))}else g=WM(m,_,A,2),g!==null&&qs(g,m,2)}function Nw(m){var g=m.alternate;return m===En||g!==null&&g===En}function z5(m,g){Np=bw=!0;var _=m.pending;_===null?g.next=g:(g.next=_.next,_.next=g),m.pending=g}function U5(m,g,_){if((_&4194048)!==0){var A=g.lanes;A&=m.pendingLanes,_|=A,g.lanes=_,gt(m,_)}}var Ex={readContext:$a,use:vw,useCallback:Si,useContext:Si,useEffect:Si,useImperativeHandle:Si,useLayoutEffect:Si,useInsertionEffect:Si,useMemo:Si,useReducer:Si,useRef:Si,useState:Si,useDebugValue:Si,useDeferredValue:Si,useTransition:Si,useSyncExternalStore:Si,useId:Si,useHostTransitionStatus:Si,useFormState:Si,useActionState:Si,useOptimistic:Si,useMemoCache:Si,useCacheRefresh:Si};Ex.useEffectEvent=Si;var B5={readContext:$a,use:vw,useCallback:function(m,g){return ks().memoizedState=[m,g===void 0?null:g],m},useContext:$a,useEffect:N5,useImperativeHandle:function(m,g,_){_=_!=null?_.concat([m]):null,_w(4194308,4,A5.bind(null,g,m),_)},useLayoutEffect:function(m,g){return _w(4194308,4,m,g)},useInsertionEffect:function(m,g){_w(4,2,m,g)},useMemo:function(m,g){var _=ks();g=g===void 0?null:g;var A=m();if(Mm){Ce(!0);try{m()}finally{Ce(!1)}}return _.memoizedState=[A,g],A},useReducer:function(m,g,_){var A=ks();if(_!==void 0){var R=_(g);if(Mm){Ce(!0);try{_(g)}finally{Ce(!1)}}}else R=g;return A.memoizedState=A.baseState=R,m={pending:null,lanes:0,dispatch:null,lastRenderedReducer:m,lastRenderedState:R},A.queue=m,m=m.dispatch=Nse.bind(null,En,m),[A.memoizedState,m]},useRef:function(m){var g=ks();return m={current:m},g.memoizedState=m},useState:function(m){m=SA(m);var g=m.queue,_=I5.bind(null,En,g);return g.dispatch=_,[m.memoizedState,_]},useDebugValue:kA,useDeferredValue:function(m,g){var _=ks();return MA(_,m,g)},useTransition:function(){var m=SA(!1);return m=D5.bind(null,En,m.queue,!0,!1),ks().memoizedState=m,[!1,m]},useSyncExternalStore:function(m,g,_){var A=En,R=ks();if(tr){if(_===void 0)throw Error(r(407));_=_()}else{if(_=g(),Ir===null)throw Error(r(349));(Qn&127)!==0||l5(A,g,_)}R.memoizedState=_;var O={value:_,getSnapshot:g};return R.queue=O,N5(u5.bind(null,A,O,m),[m]),A.flags|=2048,kp(9,{destroy:void 0},c5.bind(null,A,O,_,g),null),_},useId:function(){var m=ks(),g=Ir.identifierPrefix;if(tr){var _=oc,A=sc;_=(A&~(1<<32-Ue(A)-1)).toString(32)+_,g="_"+g+"R_"+_,_=xw++,0<_&&(g+="H"+_.toString(32)),g+="_"}else _=bse++,g="_"+g+"r_"+_.toString(32)+"_";return m.memoizedState=g},useHostTransitionStatus:TA,useFormState:y5,useActionState:y5,useOptimistic:function(m){var g=ks();g.memoizedState=g.baseState=m;var _={pending:null,lanes:0,dispatch:null,lastRenderedReducer:null,lastRenderedState:null};return g.queue=_,g=EA.bind(null,En,!0,_),_.dispatch=g,[m,g]},useMemoCache:vA,useCacheRefresh:function(){return ks().memoizedState=Sse.bind(null,En)},useEffectEvent:function(m){var g=ks(),_={impl:m};return g.memoizedState=_,function(){if((pr&2)!==0)throw Error(r(440));return _.impl.apply(void 0,arguments)}}},PA={readContext:$a,use:vw,useCallback:E5,useContext:$a,useEffect:CA,useImperativeHandle:T5,useInsertionEffect:k5,useLayoutEffect:M5,useMemo:P5,useReducer:ww,useRef:S5,useState:function(){return ww(nu)},useDebugValue:kA,useDeferredValue:function(m,g){var _=Ii();return j5(_,kr.memoizedState,m,g)},useTransition:function(){var m=ww(nu)[0],g=Ii().memoizedState;return[typeof m=="boolean"?m:Ax(m),g]},useSyncExternalStore:o5,useId:L5,useHostTransitionStatus:TA,useFormState:v5,useActionState:v5,useOptimistic:function(m,g){var _=Ii();return m5(_,kr,m,g)},useMemoCache:vA,useCacheRefresh:O5};PA.useEffectEvent=C5;var H5={readContext:$a,use:vw,useCallback:E5,useContext:$a,useEffect:CA,useImperativeHandle:T5,useInsertionEffect:k5,useLayoutEffect:M5,useMemo:P5,useReducer:_A,useRef:S5,useState:function(){return _A(nu)},useDebugValue:kA,useDeferredValue:function(m,g){var _=Ii();return kr===null?MA(_,m,g):j5(_,kr.memoizedState,m,g)},useTransition:function(){var m=_A(nu)[0],g=Ii().memoizedState;return[typeof m=="boolean"?m:Ax(m),g]},useSyncExternalStore:o5,useId:L5,useHostTransitionStatus:TA,useFormState:_5,useActionState:_5,useOptimistic:function(m,g){var _=Ii();return kr!==null?m5(_,kr,m,g):(_.baseState=m,[m,_.queue.dispatch])},useMemoCache:vA,useCacheRefresh:O5};H5.useEffectEvent=C5;function jA(m,g,_,A){g=m.memoizedState,_=_(A,g),_=_==null?g:h({},g,_),m.memoizedState=_,m.lanes===0&&(m.updateQueue.baseState=_)}var DA={enqueueSetState:function(m,g,_){m=m._reactInternals;var A=bo(),R=Ad(A);R.payload=g,_!=null&&(R.callback=_),g=Td(m,R,A),g!==null&&(qs(g,m,A),Nx(g,m,A))},enqueueReplaceState:function(m,g,_){m=m._reactInternals;var A=bo(),R=Ad(A);R.tag=1,R.payload=g,_!=null&&(R.callback=_),g=Td(m,R,A),g!==null&&(qs(g,m,A),Nx(g,m,A))},enqueueForceUpdate:function(m,g){m=m._reactInternals;var _=bo(),A=Ad(_);A.tag=2,g!=null&&(A.callback=g),g=Td(m,A,_),g!==null&&(qs(g,m,_),Nx(g,m,_))}};function $5(m,g,_,A,R,O,re){return m=m.stateNode,typeof m.shouldComponentUpdate=="function"?m.shouldComponentUpdate(A,O,re):g.prototype&&g.prototype.isPureReactComponent?!gx(_,A)||!gx(R,O):!0}function V5(m,g,_,A){m=g.state,typeof g.componentWillReceiveProps=="function"&&g.componentWillReceiveProps(_,A),typeof g.UNSAFE_componentWillReceiveProps=="function"&&g.UNSAFE_componentWillReceiveProps(_,A),g.state!==m&&DA.enqueueReplaceState(g,g.state,null)}function Am(m,g){var _=g;if("ref"in g){_={};for(var A in g)A!=="ref"&&(_[A]=g[A])}if(m=m.defaultProps){_===g&&(_=h({},_));for(var R in m)_[R]===void 0&&(_[R]=m[R])}return _}function G5(m){nw(m)}function q5(m){console.error(m)}function W5(m){nw(m)}function Cw(m,g){try{var _=m.onUncaughtError;_(g.value,{componentStack:g.stack})}catch(A){setTimeout(function(){throw A})}}function K5(m,g,_){try{var A=m.onCaughtError;A(_.value,{componentStack:_.stack,errorBoundary:g.tag===1?g.stateNode:null})}catch(R){setTimeout(function(){throw R})}}function RA(m,g,_){return _=Ad(_),_.tag=3,_.payload={element:null},_.callback=function(){Cw(m,g)},_}function X5(m){return m=Ad(m),m.tag=3,m}function Y5(m,g,_,A){var R=_.type.getDerivedStateFromError;if(typeof R=="function"){var O=A.value;m.payload=function(){return R(O)},m.callback=function(){K5(g,_,A)}}var re=_.stateNode;re!==null&&typeof re.componentDidCatch=="function"&&(m.callback=function(){K5(g,_,A),typeof R!="function"&&(Fd===null?Fd=new Set([this]):Fd.add(this));var ke=A.stack;this.componentDidCatch(A.value,{componentStack:ke!==null?ke:""})})}function Cse(m,g,_,A,R){if(_.flags|=32768,A!==null&&typeof A=="object"&&typeof A.then=="function"){if(g=_.alternate,g!==null&&xp(g,_,R,!0),_=mo.current,_!==null){switch(_.tag){case 31:case 13:return $o===null?Ow():_.alternate===null&&Ni===0&&(Ni=3),_.flags&=-257,_.flags|=65536,_.lanes=R,A===hw?_.flags|=16384:(g=_.updateQueue,g===null?_.updateQueue=new Set([A]):g.add(A),aT(m,A,R)),!1;case 22:return _.flags|=65536,A===hw?_.flags|=16384:(g=_.updateQueue,g===null?(g={transitions:null,markerInstances:null,retryQueue:new Set([A])},_.updateQueue=g):(_=g.retryQueue,_===null?g.retryQueue=new Set([A]):_.add(A)),aT(m,A,R)),!1}throw Error(r(435,_.tag))}return aT(m,A,R),Ow(),!1}if(tr)return g=mo.current,g!==null?((g.flags&65536)===0&&(g.flags|=256),g.flags|=65536,g.lanes=R,A!==JM&&(m=Error(r(422),{cause:A}),yx(zo(m,_)))):(A!==JM&&(g=Error(r(423),{cause:A}),yx(zo(g,_))),m=m.current.alternate,m.flags|=65536,R&=-R,m.lanes|=R,A=zo(A,_),R=RA(m.stateNode,A,R),uA(m,R),Ni!==4&&(Ni=2)),!1;var O=Error(r(520),{cause:A});if(O=zo(O,_),Ix===null?Ix=[O]:Ix.push(O),Ni!==4&&(Ni=2),g===null)return!0;A=zo(A,_),_=g;do{switch(_.tag){case 3:return _.flags|=65536,m=R&-R,_.lanes|=m,m=RA(_.stateNode,A,m),uA(_,m),!1;case 1:if(g=_.type,O=_.stateNode,(_.flags&128)===0&&(typeof g.getDerivedStateFromError=="function"||O!==null&&typeof O.componentDidCatch=="function"&&(Fd===null||!Fd.has(O))))return _.flags|=65536,R&=-R,_.lanes|=R,R=X5(R),Y5(R,m,_,A),uA(_,R),!1}_=_.return}while(_!==null);return!1}var FA=Error(r(461)),Ki=!1;function Va(m,g,_,A){g.child=m===null?e5(g,null,_,A):km(g,m.child,_,A)}function Q5(m,g,_,A,R){_=_.render;var O=g.ref;if("ref"in A){var re={};for(var ke in A)ke!=="ref"&&(re[ke]=A[ke])}else re=A;return _m(g),A=gA(m,g,_,re,O,R),ke=bA(),m!==null&&!Ki?(xA(m,g,R),ru(m,g,R)):(tr&&ke&&QM(g),g.flags|=1,Va(m,g,A,R),g.child)}function Z5(m,g,_,A,R){if(m===null){var O=_.type;return typeof O=="function"&&!KM(O)&&O.defaultProps===void 0&&_.compare===null?(g.tag=15,g.type=O,J5(m,g,O,A,R)):(m=sw(_.type,null,A,g,g.mode,R),m.ref=g.ref,m.return=g,g.child=m)}if(O=m.child,!$A(m,R)){var re=O.memoizedProps;if(_=_.compare,_=_!==null?_:gx,_(re,A)&&m.ref===g.ref)return ru(m,g,R)}return g.flags|=1,m=Qc(O,A),m.ref=g.ref,m.return=g,g.child=m}function J5(m,g,_,A,R){if(m!==null){var O=m.memoizedProps;if(gx(O,A)&&m.ref===g.ref)if(Ki=!1,g.pendingProps=A=O,$A(m,R))(m.flags&131072)!==0&&(Ki=!0);else return g.lanes=m.lanes,ru(m,g,R)}return LA(m,g,_,A,R)}function ez(m,g,_,A){var R=A.children,O=m!==null?m.memoizedState:null;if(m===null&&g.stateNode===null&&(g.stateNode={_visibility:1,_pendingMarkers:null,_retryCache:null,_transitions:null}),A.mode==="hidden"){if((g.flags&128)!==0){if(O=O!==null?O.baseLanes|_:_,m!==null){for(A=g.child=m.child,R=0;A!==null;)R=R|A.lanes|A.childLanes,A=A.sibling;A=R&~O}else A=0,g.child=null;return tz(m,g,O,_,A)}if((_&536870912)!==0)g.memoizedState={baseLanes:0,cachePool:null},m!==null&&uw(g,O!==null?O.cachePool:null),O!==null?r5(g,O):hA(),i5(g);else return A=g.lanes=536870912,tz(m,g,O!==null?O.baseLanes|_:_,_,A)}else O!==null?(uw(g,O.cachePool),r5(g,O),Pd(),g.memoizedState=null):(m!==null&&uw(g,null),hA(),Pd());return Va(m,g,R,_),g.child}function Px(m,g){return m!==null&&m.tag===22||g.stateNode!==null||(g.stateNode={_visibility:1,_pendingMarkers:null,_retryCache:null,_transitions:null}),g.sibling}function tz(m,g,_,A,R){var O=sA();return O=O===null?null:{parent:qi._currentValue,pool:O},g.memoizedState={baseLanes:_,cachePool:O},m!==null&&uw(g,null),hA(),i5(g),m!==null&&xp(m,g,A,!0),g.childLanes=R,null}function kw(m,g){return g=Aw({mode:g.mode,children:g.children},m.mode),g.ref=m.ref,m.child=g,g.return=m,g}function nz(m,g,_){return km(g,m.child,null,_),m=kw(g,g.pendingProps),m.flags|=2,fo(g),g.memoizedState=null,m}function kse(m,g,_){var A=g.pendingProps,R=(g.flags&128)!==0;if(g.flags&=-129,m===null){if(tr){if(A.mode==="hidden")return m=kw(g,A),g.lanes=536870912,Px(null,m);if(fA(g),(m=ei)?(m=fU(m,Ho),m=m!==null&&m.data==="&"?m:null,m!==null&&(g.memoizedState={dehydrated:m,treeContext:Sd!==null?{id:sc,overflow:oc}:null,retryLane:536870912,hydrationErrors:null},_=zI(m),_.return=g,g.child=_,Ha=g,ei=null)):m=null,m===null)throw Cd(g);return g.lanes=536870912,null}return kw(g,A)}var O=m.memoizedState;if(O!==null){var re=O.dehydrated;if(fA(g),R)if(g.flags&256)g.flags&=-257,g=nz(m,g,_);else if(g.memoizedState!==null)g.child=m.child,g.flags|=128,g=null;else throw Error(r(558));else if(Ki||xp(m,g,_,!1),R=(_&m.childLanes)!==0,Ki||R){if(A=Ir,A!==null&&(re=Qt(A,_),re!==0&&re!==O.retryLane))throw O.retryLane=re,xm(m,re),qs(A,m,re),FA;Ow(),g=nz(m,g,_)}else m=O.treeContext,ei=Vo(re.nextSibling),Ha=g,tr=!0,Nd=null,Ho=!1,m!==null&&HI(g,m),g=kw(g,A),g.flags|=4096;return g}return m=Qc(m.child,{mode:A.mode,children:A.children}),m.ref=g.ref,g.child=m,m.return=g,m}function Mw(m,g){var _=g.ref;if(_===null)m!==null&&m.ref!==null&&(g.flags|=4194816);else{if(typeof _!="function"&&typeof _!="object")throw Error(r(284));(m===null||m.ref!==_)&&(g.flags|=4194816)}}function LA(m,g,_,A,R){return _m(g),_=gA(m,g,_,A,void 0,R),A=bA(),m!==null&&!Ki?(xA(m,g,R),ru(m,g,R)):(tr&&A&&QM(g),g.flags|=1,Va(m,g,_,R),g.child)}function rz(m,g,_,A,R,O){return _m(g),g.updateQueue=null,_=s5(g,A,_,R),a5(m),A=bA(),m!==null&&!Ki?(xA(m,g,O),ru(m,g,O)):(tr&&A&&QM(g),g.flags|=1,Va(m,g,_,O),g.child)}function iz(m,g,_,A,R){if(_m(g),g.stateNode===null){var O=fp,re=_.contextType;typeof re=="object"&&re!==null&&(O=$a(re)),O=new _(A,O),g.memoizedState=O.state!==null&&O.state!==void 0?O.state:null,O.updater=DA,g.stateNode=O,O._reactInternals=g,O=g.stateNode,O.props=A,O.state=g.memoizedState,O.refs={},lA(g),re=_.contextType,O.context=typeof re=="object"&&re!==null?$a(re):fp,O.state=g.memoizedState,re=_.getDerivedStateFromProps,typeof re=="function"&&(jA(g,_,re,A),O.state=g.memoizedState),typeof _.getDerivedStateFromProps=="function"||typeof O.getSnapshotBeforeUpdate=="function"||typeof O.UNSAFE_componentWillMount!="function"&&typeof O.componentWillMount!="function"||(re=O.state,typeof O.componentWillMount=="function"&&O.componentWillMount(),typeof O.UNSAFE_componentWillMount=="function"&&O.UNSAFE_componentWillMount(),re!==O.state&&DA.enqueueReplaceState(O,O.state,null),kx(g,A,O,R),Cx(),O.state=g.memoizedState),typeof O.componentDidMount=="function"&&(g.flags|=4194308),A=!0}else if(m===null){O=g.stateNode;var ke=g.memoizedProps,Be=Am(_,ke);O.props=Be;var ut=O.context,wt=_.contextType;re=fp,typeof wt=="object"&&wt!==null&&(re=$a(wt));var kt=_.getDerivedStateFromProps;wt=typeof kt=="function"||typeof O.getSnapshotBeforeUpdate=="function",ke=g.pendingProps!==ke,wt||typeof O.UNSAFE_componentWillReceiveProps!="function"&&typeof O.componentWillReceiveProps!="function"||(ke||ut!==re)&&V5(g,O,A,re),Md=!1;var mt=g.memoizedState;O.state=mt,kx(g,A,O,R),Cx(),ut=g.memoizedState,ke||mt!==ut||Md?(typeof kt=="function"&&(jA(g,_,kt,A),ut=g.memoizedState),(Be=Md||$5(g,_,Be,A,mt,ut,re))?(wt||typeof O.UNSAFE_componentWillMount!="function"&&typeof O.componentWillMount!="function"||(typeof O.componentWillMount=="function"&&O.componentWillMount(),typeof O.UNSAFE_componentWillMount=="function"&&O.UNSAFE_componentWillMount()),typeof O.componentDidMount=="function"&&(g.flags|=4194308)):(typeof O.componentDidMount=="function"&&(g.flags|=4194308),g.memoizedProps=A,g.memoizedState=ut),O.props=A,O.state=ut,O.context=re,A=Be):(typeof O.componentDidMount=="function"&&(g.flags|=4194308),A=!1)}else{O=g.stateNode,cA(m,g),re=g.memoizedProps,wt=Am(_,re),O.props=wt,kt=g.pendingProps,mt=O.context,ut=_.contextType,Be=fp,typeof ut=="object"&&ut!==null&&(Be=$a(ut)),ke=_.getDerivedStateFromProps,(ut=typeof ke=="function"||typeof O.getSnapshotBeforeUpdate=="function")||typeof O.UNSAFE_componentWillReceiveProps!="function"&&typeof O.componentWillReceiveProps!="function"||(re!==kt||mt!==Be)&&V5(g,O,A,Be),Md=!1,mt=g.memoizedState,O.state=mt,kx(g,A,O,R),Cx();var xt=g.memoizedState;re!==kt||mt!==xt||Md||m!==null&&m.dependencies!==null&&lw(m.dependencies)?(typeof ke=="function"&&(jA(g,_,ke,A),xt=g.memoizedState),(wt=Md||$5(g,_,wt,A,mt,xt,Be)||m!==null&&m.dependencies!==null&&lw(m.dependencies))?(ut||typeof O.UNSAFE_componentWillUpdate!="function"&&typeof O.componentWillUpdate!="function"||(typeof O.componentWillUpdate=="function"&&O.componentWillUpdate(A,xt,Be),typeof O.UNSAFE_componentWillUpdate=="function"&&O.UNSAFE_componentWillUpdate(A,xt,Be)),typeof O.componentDidUpdate=="function"&&(g.flags|=4),typeof O.getSnapshotBeforeUpdate=="function"&&(g.flags|=1024)):(typeof O.componentDidUpdate!="function"||re===m.memoizedProps&&mt===m.memoizedState||(g.flags|=4),typeof O.getSnapshotBeforeUpdate!="function"||re===m.memoizedProps&&mt===m.memoizedState||(g.flags|=1024),g.memoizedProps=A,g.memoizedState=xt),O.props=A,O.state=xt,O.context=Be,A=wt):(typeof O.componentDidUpdate!="function"||re===m.memoizedProps&&mt===m.memoizedState||(g.flags|=4),typeof O.getSnapshotBeforeUpdate!="function"||re===m.memoizedProps&&mt===m.memoizedState||(g.flags|=1024),A=!1)}return O=A,Mw(m,g),A=(g.flags&128)!==0,O||A?(O=g.stateNode,_=A&&typeof _.getDerivedStateFromError!="function"?null:O.render(),g.flags|=1,m!==null&&A?(g.child=km(g,m.child,null,R),g.child=km(g,null,_,R)):Va(m,g,_,R),g.memoizedState=O.state,m=g.child):m=ru(m,g,R),m}function az(m,g,_,A){return vm(),g.flags|=256,Va(m,g,_,A),g.child}var OA={dehydrated:null,treeContext:null,retryLane:0,hydrationErrors:null};function IA(m){return{baseLanes:m,cachePool:KI()}}function zA(m,g,_){return m=m!==null?m.childLanes&~_:0,g&&(m|=go),m}function sz(m,g,_){var A=g.pendingProps,R=!1,O=(g.flags&128)!==0,re;if((re=O)||(re=m!==null&&m.memoizedState===null?!1:(Oi.current&2)!==0),re&&(R=!0,g.flags&=-129),re=(g.flags&32)!==0,g.flags&=-33,m===null){if(tr){if(R?Ed(g):Pd(),(m=ei)?(m=fU(m,Ho),m=m!==null&&m.data!=="&"?m:null,m!==null&&(g.memoizedState={dehydrated:m,treeContext:Sd!==null?{id:sc,overflow:oc}:null,retryLane:536870912,hydrationErrors:null},_=zI(m),_.return=g,g.child=_,Ha=g,ei=null)):m=null,m===null)throw Cd(g);return wT(m)?g.lanes=32:g.lanes=536870912,null}var ke=A.children;return A=A.fallback,R?(Pd(),R=g.mode,ke=Aw({mode:"hidden",children:ke},R),A=ym(A,R,_,null),ke.return=g,A.return=g,ke.sibling=A,g.child=ke,A=g.child,A.memoizedState=IA(_),A.childLanes=zA(m,re,_),g.memoizedState=OA,Px(null,A)):(Ed(g),UA(g,ke))}var Be=m.memoizedState;if(Be!==null&&(ke=Be.dehydrated,ke!==null)){if(O)g.flags&256?(Ed(g),g.flags&=-257,g=BA(m,g,_)):g.memoizedState!==null?(Pd(),g.child=m.child,g.flags|=128,g=null):(Pd(),ke=A.fallback,R=g.mode,A=Aw({mode:"visible",children:A.children},R),ke=ym(ke,R,_,null),ke.flags|=2,A.return=g,ke.return=g,A.sibling=ke,g.child=A,km(g,m.child,null,_),A=g.child,A.memoizedState=IA(_),A.childLanes=zA(m,re,_),g.memoizedState=OA,g=Px(null,A));else if(Ed(g),wT(ke)){if(re=ke.nextSibling&&ke.nextSibling.dataset,re)var ut=re.dgst;re=ut,A=Error(r(419)),A.stack="",A.digest=re,yx({value:A,source:null,stack:null}),g=BA(m,g,_)}else if(Ki||xp(m,g,_,!1),re=(_&m.childLanes)!==0,Ki||re){if(re=Ir,re!==null&&(A=Qt(re,_),A!==0&&A!==Be.retryLane))throw Be.retryLane=A,xm(m,A),qs(re,m,A),FA;vT(ke)||Ow(),g=BA(m,g,_)}else vT(ke)?(g.flags|=192,g.child=m.child,g=null):(m=Be.treeContext,ei=Vo(ke.nextSibling),Ha=g,tr=!0,Nd=null,Ho=!1,m!==null&&HI(g,m),g=UA(g,A.children),g.flags|=4096);return g}return R?(Pd(),ke=A.fallback,R=g.mode,Be=m.child,ut=Be.sibling,A=Qc(Be,{mode:"hidden",children:A.children}),A.subtreeFlags=Be.subtreeFlags&65011712,ut!==null?ke=Qc(ut,ke):(ke=ym(ke,R,_,null),ke.flags|=2),ke.return=g,A.return=g,A.sibling=ke,g.child=A,Px(null,A),A=g.child,ke=m.child.memoizedState,ke===null?ke=IA(_):(R=ke.cachePool,R!==null?(Be=qi._currentValue,R=R.parent!==Be?{parent:Be,pool:Be}:R):R=KI(),ke={baseLanes:ke.baseLanes|_,cachePool:R}),A.memoizedState=ke,A.childLanes=zA(m,re,_),g.memoizedState=OA,Px(m.child,A)):(Ed(g),_=m.child,m=_.sibling,_=Qc(_,{mode:"visible",children:A.children}),_.return=g,_.sibling=null,m!==null&&(re=g.deletions,re===null?(g.deletions=[m],g.flags|=16):re.push(m)),g.child=_,g.memoizedState=null,_)}function UA(m,g){return g=Aw({mode:"visible",children:g},m.mode),g.return=m,m.child=g}function Aw(m,g){return m=ho(22,m,null,g),m.lanes=0,m}function BA(m,g,_){return km(g,m.child,null,_),m=UA(g,g.pendingProps.children),m.flags|=2,g.memoizedState=null,m}function oz(m,g,_){m.lanes|=g;var A=m.alternate;A!==null&&(A.lanes|=g),nA(m.return,g,_)}function HA(m,g,_,A,R,O){var re=m.memoizedState;re===null?m.memoizedState={isBackwards:g,rendering:null,renderingStartTime:0,last:A,tail:_,tailMode:R,treeForkCount:O}:(re.isBackwards=g,re.rendering=null,re.renderingStartTime=0,re.last=A,re.tail=_,re.tailMode=R,re.treeForkCount=O)}function lz(m,g,_){var A=g.pendingProps,R=A.revealOrder,O=A.tail;A=A.children;var re=Oi.current,ke=(re&2)!==0;if(ke?(re=re&1|2,g.flags|=128):re&=1,ne(Oi,re),Va(m,g,A,_),A=tr?xx:0,!ke&&m!==null&&(m.flags&128)!==0)e:for(m=g.child;m!==null;){if(m.tag===13)m.memoizedState!==null&&oz(m,_,g);else if(m.tag===19)oz(m,_,g);else if(m.child!==null){m.child.return=m,m=m.child;continue}if(m===g)break e;for(;m.sibling===null;){if(m.return===null||m.return===g)break e;m=m.return}m.sibling.return=m.return,m=m.sibling}switch(R){case"forwards":for(_=g.child,R=null;_!==null;)m=_.alternate,m!==null&&gw(m)===null&&(R=_),_=_.sibling;_=R,_===null?(R=g.child,g.child=null):(R=_.sibling,_.sibling=null),HA(g,!1,R,_,O,A);break;case"backwards":case"unstable_legacy-backwards":for(_=null,R=g.child,g.child=null;R!==null;){if(m=R.alternate,m!==null&&gw(m)===null){g.child=R;break}m=R.sibling,R.sibling=_,_=R,R=m}HA(g,!0,_,null,O,A);break;case"together":HA(g,!1,null,null,void 0,A);break;default:g.memoizedState=null}return g.child}function ru(m,g,_){if(m!==null&&(g.dependencies=m.dependencies),Rd|=g.lanes,(_&g.childLanes)===0)if(m!==null){if(xp(m,g,_,!1),(_&g.childLanes)===0)return null}else return null;if(m!==null&&g.child!==m.child)throw Error(r(153));if(g.child!==null){for(m=g.child,_=Qc(m,m.pendingProps),g.child=_,_.return=g;m.sibling!==null;)m=m.sibling,_=_.sibling=Qc(m,m.pendingProps),_.return=g;_.sibling=null}return g.child}function $A(m,g){return(m.lanes&g)!==0?!0:(m=m.dependencies,!!(m!==null&&lw(m)))}function Mse(m,g,_){switch(g.tag){case 3:Re(g,g.stateNode.containerInfo),kd(g,qi,m.memoizedState.cache),vm();break;case 27:case 5:le(g);break;case 4:Re(g,g.stateNode.containerInfo);break;case 10:kd(g,g.type,g.memoizedProps.value);break;case 31:if(g.memoizedState!==null)return g.flags|=128,fA(g),null;break;case 13:var A=g.memoizedState;if(A!==null)return A.dehydrated!==null?(Ed(g),g.flags|=128,null):(_&g.child.childLanes)!==0?sz(m,g,_):(Ed(g),m=ru(m,g,_),m!==null?m.sibling:null);Ed(g);break;case 19:var R=(m.flags&128)!==0;if(A=(_&g.childLanes)!==0,A||(xp(m,g,_,!1),A=(_&g.childLanes)!==0),R){if(A)return lz(m,g,_);g.flags|=128}if(R=g.memoizedState,R!==null&&(R.rendering=null,R.tail=null,R.lastEffect=null),ne(Oi,Oi.current),A)break;return null;case 22:return g.lanes=0,ez(m,g,_,g.pendingProps);case 24:kd(g,qi,m.memoizedState.cache)}return ru(m,g,_)}function cz(m,g,_){if(m!==null)if(m.memoizedProps!==g.pendingProps)Ki=!0;else{if(!$A(m,_)&&(g.flags&128)===0)return Ki=!1,Mse(m,g,_);Ki=(m.flags&131072)!==0}else Ki=!1,tr&&(g.flags&1048576)!==0&&BI(g,xx,g.index);switch(g.lanes=0,g.tag){case 16:e:{var A=g.pendingProps;if(m=Nm(g.elementType),g.type=m,typeof m=="function")KM(m)?(A=Am(m,A),g.tag=1,g=iz(null,g,m,A,_)):(g.tag=0,g=LA(null,g,m,A,_));else{if(m!=null){var R=m.$$typeof;if(R===M){g.tag=11,g=Q5(null,g,m,A,_);break e}else if(R===C){g.tag=14,g=Z5(null,g,m,A,_);break e}}throw g=D(m)||m,Error(r(306,g,""))}}return g;case 0:return LA(m,g,g.type,g.pendingProps,_);case 1:return A=g.type,R=Am(A,g.pendingProps),iz(m,g,A,R,_);case 3:e:{if(Re(g,g.stateNode.containerInfo),m===null)throw Error(r(387));A=g.pendingProps;var O=g.memoizedState;R=O.element,cA(m,g),kx(g,A,null,_);var re=g.memoizedState;if(A=re.cache,kd(g,qi,A),A!==O.cache&&rA(g,[qi],_,!0),Cx(),A=re.element,O.isDehydrated)if(O={element:A,isDehydrated:!1,cache:re.cache},g.updateQueue.baseState=O,g.memoizedState=O,g.flags&256){g=az(m,g,A,_);break e}else if(A!==R){R=zo(Error(r(424)),g),yx(R),g=az(m,g,A,_);break e}else for(m=g.stateNode.containerInfo,m.nodeType===9?m=m.body:m=m.nodeName==="HTML"?m.ownerDocument.body:m,ei=Vo(m.firstChild),Ha=g,tr=!0,Nd=null,Ho=!0,_=e5(g,null,A,_),g.child=_;_;)_.flags=_.flags&-3|4096,_=_.sibling;else{if(vm(),A===R){g=ru(m,g,_);break e}Va(m,g,A,_)}g=g.child}return g;case 26:return Mw(m,g),m===null?(_=vU(g.type,null,g.pendingProps,null))?g.memoizedState=_:tr||(_=g.type,m=g.pendingProps,A=Vw(me.current).createElement(_),A[Xt]=g,A[or]=m,Ga(A,_,m),Ge(A),g.stateNode=A):g.memoizedState=vU(g.type,m.memoizedProps,g.pendingProps,m.memoizedState),null;case 27:return le(g),m===null&&tr&&(A=g.stateNode=bU(g.type,g.pendingProps,me.current),Ha=g,Ho=!0,R=ei,zd(g.type)?(_T=R,ei=Vo(A.firstChild)):ei=R),Va(m,g,g.pendingProps.children,_),Mw(m,g),m===null&&(g.flags|=4194304),g.child;case 5:return m===null&&tr&&((R=A=ei)&&(A=roe(A,g.type,g.pendingProps,Ho),A!==null?(g.stateNode=A,Ha=g,ei=Vo(A.firstChild),Ho=!1,R=!0):R=!1),R||Cd(g)),le(g),R=g.type,O=g.pendingProps,re=m!==null?m.memoizedProps:null,A=O.children,bT(R,O)?A=null:re!==null&&bT(R,re)&&(g.flags|=32),g.memoizedState!==null&&(R=gA(m,g,xse,null,null,_),qx._currentValue=R),Mw(m,g),Va(m,g,A,_),g.child;case 6:return m===null&&tr&&((m=_=ei)&&(_=ioe(_,g.pendingProps,Ho),_!==null?(g.stateNode=_,Ha=g,ei=null,m=!0):m=!1),m||Cd(g)),null;case 13:return sz(m,g,_);case 4:return Re(g,g.stateNode.containerInfo),A=g.pendingProps,m===null?g.child=km(g,null,A,_):Va(m,g,A,_),g.child;case 11:return Q5(m,g,g.type,g.pendingProps,_);case 7:return Va(m,g,g.pendingProps,_),g.child;case 8:return Va(m,g,g.pendingProps.children,_),g.child;case 12:return Va(m,g,g.pendingProps.children,_),g.child;case 10:return A=g.pendingProps,kd(g,g.type,A.value),Va(m,g,A.children,_),g.child;case 9:return R=g.type._context,A=g.pendingProps.children,_m(g),R=$a(R),A=A(R),g.flags|=1,Va(m,g,A,_),g.child;case 14:return Z5(m,g,g.type,g.pendingProps,_);case 15:return J5(m,g,g.type,g.pendingProps,_);case 19:return lz(m,g,_);case 31:return kse(m,g,_);case 22:return ez(m,g,_,g.pendingProps);case 24:return _m(g),A=$a(qi),m===null?(R=sA(),R===null&&(R=Ir,O=iA(),R.pooledCache=O,O.refCount++,O!==null&&(R.pooledCacheLanes|=_),R=O),g.memoizedState={parent:A,cache:R},lA(g),kd(g,qi,R)):((m.lanes&_)!==0&&(cA(m,g),kx(g,null,null,_),Cx()),R=m.memoizedState,O=g.memoizedState,R.parent!==A?(R={parent:A,cache:A},g.memoizedState=R,g.lanes===0&&(g.memoizedState=g.updateQueue.baseState=R),kd(g,qi,A)):(A=O.cache,kd(g,qi,A),A!==R.cache&&rA(g,[qi],_,!0))),Va(m,g,g.pendingProps.children,_),g.child;case 29:throw g.pendingProps}throw Error(r(156,g.tag))}function iu(m){m.flags|=4}function VA(m,g,_,A,R){if((g=(m.mode&32)!==0)&&(g=!1),g){if(m.flags|=16777216,(R&335544128)===R)if(m.stateNode.complete)m.flags|=8192;else if(Lz())m.flags|=8192;else throw Cm=hw,oA}else m.flags&=-16777217}function uz(m,g){if(g.type!=="stylesheet"||(g.state.loading&4)!==0)m.flags&=-16777217;else if(m.flags|=16777216,!CU(g))if(Lz())m.flags|=8192;else throw Cm=hw,oA}function Tw(m,g){g!==null&&(m.flags|=4),m.flags&16384&&(g=m.tag!==22?yt():536870912,m.lanes|=g,Ep|=g)}function jx(m,g){if(!tr)switch(m.tailMode){case"hidden":g=m.tail;for(var _=null;g!==null;)g.alternate!==null&&(_=g),g=g.sibling;_===null?m.tail=null:_.sibling=null;break;case"collapsed":_=m.tail;for(var A=null;_!==null;)_.alternate!==null&&(A=_),_=_.sibling;A===null?g||m.tail===null?m.tail=null:m.tail.sibling=null:A.sibling=null}}function ti(m){var g=m.alternate!==null&&m.alternate.child===m.child,_=0,A=0;if(g)for(var R=m.child;R!==null;)_|=R.lanes|R.childLanes,A|=R.subtreeFlags&65011712,A|=R.flags&65011712,R.return=m,R=R.sibling;else for(R=m.child;R!==null;)_|=R.lanes|R.childLanes,A|=R.subtreeFlags,A|=R.flags,R.return=m,R=R.sibling;return m.subtreeFlags|=A,m.childLanes=_,g}function Ase(m,g,_){var A=g.pendingProps;switch(ZM(g),g.tag){case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return ti(g),null;case 1:return ti(g),null;case 3:return _=g.stateNode,A=null,m!==null&&(A=m.memoizedState.cache),g.memoizedState.cache!==A&&(g.flags|=2048),eu(qi),ue(),_.pendingContext&&(_.context=_.pendingContext,_.pendingContext=null),(m===null||m.child===null)&&(bp(g)?iu(g):m===null||m.memoizedState.isDehydrated&&(g.flags&256)===0||(g.flags|=1024,eA())),ti(g),null;case 26:var R=g.type,O=g.memoizedState;return m===null?(iu(g),O!==null?(ti(g),uz(g,O)):(ti(g),VA(g,R,null,A,_))):O?O!==m.memoizedState?(iu(g),ti(g),uz(g,O)):(ti(g),g.flags&=-16777217):(m=m.memoizedProps,m!==A&&iu(g),ti(g),VA(g,R,m,A,_)),null;case 27:if(Ne(g),_=me.current,R=g.type,m!==null&&g.stateNode!=null)m.memoizedProps!==A&&iu(g);else{if(!A){if(g.stateNode===null)throw Error(r(166));return ti(g),null}m=te.current,bp(g)?$I(g):(m=bU(R,A,_),g.stateNode=m,iu(g))}return ti(g),null;case 5:if(Ne(g),R=g.type,m!==null&&g.stateNode!=null)m.memoizedProps!==A&&iu(g);else{if(!A){if(g.stateNode===null)throw Error(r(166));return ti(g),null}if(O=te.current,bp(g))$I(g);else{var re=Vw(me.current);switch(O){case 1:O=re.createElementNS("http://www.w3.org/2000/svg",R);break;case 2:O=re.createElementNS("http://www.w3.org/1998/Math/MathML",R);break;default:switch(R){case"svg":O=re.createElementNS("http://www.w3.org/2000/svg",R);break;case"math":O=re.createElementNS("http://www.w3.org/1998/Math/MathML",R);break;case"script":O=re.createElement("div"),O.innerHTML=" +