diff --git a/transition/alert-inventory/README.md b/transition/alert-inventory/README.md new file mode 100644 index 0000000..338a8f4 --- /dev/null +++ b/transition/alert-inventory/README.md @@ -0,0 +1,216 @@ +# Alert Inventory + +This workflow helps users fetch the alert configurations currently enabled in Classic Central. It creates a read-only inventory of the alert assignments visible to the supplied access token, making it easier to review what is active and export the results for review, validation, or recordkeeping. + +The tool fetches enabled alerts and sorts assignments by scope, severity, etc. & then download the configuration as JSON or CSV. + +```mermaid +flowchart LR + credentials["Provide
credentials"] --> fetch["Fetch enabled
Classic Central alerts"] + fetch --> review["Review enabled-alert
inventory"] + review --> export["Export CSV/JSON
for transition assessment"] + + classDef credentials fill:#202e3a,stroke:#78909f,color:#f4f8fb,stroke-width:2px; + classDef retrieval fill:#153c56,stroke:#8fd0ff,color:#f4f8fb,stroke-width:2px; + classDef review fill:#242d61,stroke:#9ca7ff,color:#f4f8fb,stroke-width:2px; + classDef export fill:#173d2d,stroke:#86d7ad,color:#f4f8fb,stroke-width:2px; + + class credentials credentials; + class fetch retrieval; + class review review; + class export export; +``` + +![Animation showing enabled alerts being reviewed and exported as CSV](docs/enabled-alerts-workflow.gif) + +## Features + +- **Enabled Alert Retrieval** - Fetches the alert configurations currently enabled in Classic Central and visible to the supplied access token +- **UI Review** - Lets users start an extraction, monitor retrieval progress, and review completed results in a browser +- **Scope-Aware Inventory** - Groups enabled alert assignments by scope so users can understand where each alert applies +- **JSON and CSV Exports** - Downloads the complete schema-v1 JSON inventory or a readable CSV companion from the UI +- **CLI Support** - Provides a command-line alternative that writes a timestamped schema-v1 JSON export +- **Read-Only Operation** - Does not change Central configuration or apply alert settings + +Results are limited to enabled alert settings visible to the supplied token. Disabled settings are not exported. + +## Prerequisites + +- Python 3.10 or later +- Network access to the Classic Central API origin +- A Classic Central access token authorized to read alert settings + +## Installation + +1. Clone this repository and open its directory: + +```sh +git clone -b v2 https://github.com/aruba/central-python-workflows.git +cd transition/alert-inventory +``` + +2. Create a virtual environment and install the dependencies for your platform. + +### macOS and Linux + +```sh +python3 -m venv .venv +source .venv/bin/activate +python3 -m pip install -r requirements.txt +``` + +### Windows PowerShell + +```powershell +py -3 -m venv .venv +.venv\Scripts\Activate.ps1 +py -3 -m pip install -r requirements.txt +``` + +`requirements.txt` installs pinned compatible FastAPI and Uvicorn versions. + +## Configuration + +### UI Credentials (Recommended) + +Select a Classic Central cluster and enter its access token in the browser. + +### Saved Credentials (Optional) + +Select **Save token on this device** before starting an extraction to retain the token for a later UI launch. The service writes `token.json` atomically, with restricted file permissions where supported, only after access validation and a successful extraction. A later UI launch automatically starts an extraction when it finds a structurally valid saved token. If the token is invalid or expired, the file remains unchanged and the UI keeps the selected cluster while requesting a replacement token. + +> [!WARNING] +> `token.json` contains an access token. It is gitignored, but keep it private: never commit, share, or paste it into an issue. + +### CLI Credentials (Alternative) + +The CLI reads `token.json` from the repository root. This is the same optional credential store used by the UI. Copy the example, then edit the copy: + +**macOS and Linux** + +```sh +cp token.json.example token.json +``` + +**Windows PowerShell** + +```powershell +Copy-Item token.json.example token.json +``` + +Use this nested structure: + +```json +{ + "base_url": "CENTRAL_BASE_URL", + "token": { + "access_token": "REPLACE_WITH_YOUR_CLASSIC_CENTRAL_ACCESS_TOKEN" + } +} +``` + +`base_url` must be the HTTPS origin for the Classic Central account. Include the scheme and optional port, but no path, query, fragment, or credentials. `token.access_token` must be a non-empty string. + +## Execution + +### UI (Recommended) + +Run the UI from the repository root: + +```sh +python3 -m alert_inventory.ui +``` + +To choose a port: + +```sh +python3 -m alert_inventory.ui --port 9000 +``` + +Use this command on Windows PowerShell: + +```powershell +py -3 -m alert_inventory.ui +``` + +The command prints the complete `http://127.0.0.1:PORT/` URL and opens it in the default browser. If the browser does not open, copy the printed URL into Chrome or Edge on the same computer. The UI supports current versions of Chrome and Edge on desktop. Mobile browsers are outside the supported scope. Keep the terminal open while using the application, and press `Ctrl+C` there to stop the service cleanly. + +The UI shows access validation and page-level retrieved counts. A cancellation request stops before the next request or retry; an already in-flight request can continue until its timeout, and partial results are discarded. Retrying a recoverable failure reuses credentials held only in local process memory without sending the token back from the browser. + +### CLI (Alternative) + +Run the CLI extraction from the repository root: + +```sh +python3 -m alert_inventory.cli extract +``` + +Use this command on Windows PowerShell: + +```powershell +py -3 -m alert_inventory.cli extract +``` + +| Option | Description | +| --- | --- | +| `--output PATH` | Write the export to `PATH` instead of the default timestamped file. | +| `--overwrite` | Replace an existing `--output PATH` file. It cannot be used without `--output`. | + +Examples: + +```sh +python3 -m alert_inventory.cli extract --output customer-alerts.json +python3 -m alert_inventory.cli extract --output customer-alerts.json --overwrite +``` + +Use `python3 -m alert_inventory.cli --help`, `python3 -m alert_inventory.cli extract --help`, or `python3 -m alert_inventory.ui --help` for command help. + +## Output + +### UI Results + +Completed results remain available in **Previous runs** only while the UI process is running. Select a completed run to review it again, download its complete source export with **Download all as JSON**, or download its readable companion with **Download all as CSV**. Search and filters never limit either download. Stopping the UI clears this in-memory history. + +The results view groups enabled alert assignments by scope: + +![Hierarchy-aware enabled alert assignments grouped by scope](docs/enabled-alerts-results.png) + +The CSV contains one row per alert assignment and starts with these eight columns: Scope type, Scope, Alert, Category, Severity, Conditions, Duration, and Notification options. Multiple notification options use `; `, multiple targets within one option use `, `, and absent values are blank. Downloads use UTF-8 with a BOM and CRLF line endings. The CSV is a readable flattened view; the JSON download remains the canonical schema-v1 export. + +![Sanitized preview of the readable enabled-alert CSV export](docs/enabled-alerts-csv.png) + +### CLI JSON Export + +Without `--output`, the CLI writes a timestamped file in the current directory: + +```text +classic-central-enabled-alert-configs-YYYYMMDDTHHMMSSZ.json +``` + +The schema-v1 JSON document contains `schema_version`, `source` (the endpoint and extraction timestamp), `counts` (reported, retrieved, enabled, and disabled), and `settings` (the enabled alert settings). + +> [!WARNING] +> JSON and CSV exports can contain sensitive user configuration. Store them securely and do not share them publicly. + +## Troubleshooting + +| Problem | Fix | +| --- | --- | +| Invalid access (HTTP `401` or `403`) | Enter a new access token and start another extraction. | +| Rate limited (HTTP `429`) | Wait a few minutes, then retry this extraction. | +| Service unavailable (HTTP `5xx`) | Classic Central is temporarily unavailable. Retry this extraction. | +| Request rejected (another HTTP status) | Check the selected cluster and access token, then start a new extraction. | +| Network failure (no HTTP status) | Check the network connection, then retry this extraction. | +| Browser does not open | Copy the printed `http://127.0.0.1:PORT/` URL into Chrome or Edge on the same computer. | +| Local port cannot be reached | Confirm the command is still running and use the exact printed URL; the service accepts connections only. | +| UI assets are missing | Restore or download a complete, unmodified source checkout. | +| `Extraction failed.` | Confirm that `token.json` is a regular file in the repository root, contains valid JSON, and has the exact nested credential shape above. | +| Credential configuration is rejected | Confirm `base_url` is an HTTPS origin only, without a path or query, and `token.access_token` is non-empty. | +| The output file already exists | Choose another `--output` path, or add `--overwrite` with an explicit `--output` path. | +| The export is empty | Confirm that the token can view enabled notification settings; disabled settings are not exported. | + +## Support + +- **Automation Team**: [aruba-automation@hpe.com](mailto:aruba-automation@hpe.com) +- **Workflow Issues**: [GitHub Issues](https://github.com/aruba/central-python-workflows/issues) +- **PyCentral Library**: [PyCentral Issues](https://github.com/aruba/pycentral/issues) diff --git a/transition/alert-inventory/alert_inventory/__init__.py b/transition/alert-inventory/alert_inventory/__init__.py new file mode 100644 index 0000000..87c6d13 --- /dev/null +++ b/transition/alert-inventory/alert_inventory/__init__.py @@ -0,0 +1 @@ +"""Alert Inventory helpers.""" diff --git a/transition/alert-inventory/alert_inventory/catalog.py b/transition/alert-inventory/alert_inventory/catalog.py new file mode 100644 index 0000000..3573513 --- /dev/null +++ b/transition/alert-inventory/alert_inventory/catalog.py @@ -0,0 +1,365 @@ +"""Canonical Classic Central alert catalog construction and resolution.""" + +from __future__ import annotations + +import json +import threading +from collections.abc import Callable, Mapping, Sequence +from dataclasses import dataclass +from pathlib import Path +from types import MappingProxyType +from typing import Any + +from .classic_types import ApiAlertType + + +APPROVED_DIFFERENCE_REASON = "approved_api_ui_name_difference" +NAME_MATCHES = frozenset({"exact", "approved_difference"}) +_NOT_FETCHED = object() +_LOOKUP_FAILED = object() + + +@dataclass(frozen=True) +class UiAlert: + """One reviewed Classic Central UI alert.""" + + category: str + display_name: str + api_match: Mapping[str, str] | None = None + + def __post_init__(self) -> None: + if self.api_match is not None: + if not isinstance(self.api_match, Mapping): + raise ValueError("api_match must be an object") + object.__setattr__( + self, + "api_match", + MappingProxyType(dict(self.api_match)), + ) + + +@dataclass(frozen=True) +class CatalogEntry: + """One canonical mapping from an API source type to a UI alert.""" + + api_id: int + source_type: str + api_display_name: str + display_name: str + category: str + name_match: str + + +@dataclass(frozen=True) +class ResolvedAlert: + """A catalog or live API resolution without any delivery configuration.""" + + source_type: str + display_name: str + category: str | None + api_display_name: str | None + api_id: int | None + name_match: str | None + api_only: bool + unmapped: bool + warning_code: str | None + + +class AlertResolver: + """Resolve catalog alerts and lazily fetch API-only definitions once.""" + + def __init__( + self, + catalog: Mapping[str, CatalogEntry], + *, + fetcher: Callable[[], Sequence[ApiAlertType]], + ) -> None: + self._catalog = catalog + self._fetcher = fetcher + self._live_types: tuple[ApiAlertType, ...] | object = _NOT_FETCHED + self._live_types_lock = threading.Lock() + + def resolve(self, source_type: str) -> ResolvedAlert: + """Resolve one source type without retrying a failed live lookup.""" + + if not isinstance(source_type, str) or not source_type: + raise ValueError("source_type must be a non-empty string") + if source_type in self._catalog: + return resolve_alert(source_type, self._catalog) + + if self._live_types is _NOT_FETCHED: + with self._live_types_lock: + if self._live_types is _NOT_FETCHED: + try: + live_types = tuple(self._fetcher()) + source_types: set[str] = set() + for api_type in live_types: + _validate_api_type(api_type) + if api_type.name in source_types: + raise ValueError("duplicate source type") + source_types.add(api_type.name) + self._live_types = live_types + except Exception: + self._live_types = _LOOKUP_FAILED + + if self._live_types is _LOOKUP_FAILED: + return _unmapped_alert( + source_type, + warning_code="notification_types_lookup_failed", + ) + return resolve_alert( + source_type, + self._catalog, + live_types=self._live_types, + ) + + +def _read_json(path: Path, document_name: str) -> Any: + try: + return json.loads(path.read_text(encoding="utf-8")) + except (OSError, json.JSONDecodeError) as exc: + raise ValueError(f"{document_name} must contain valid JSON") from exc + + +def _require_string(record: Mapping[str, Any], field: str, document_name: str) -> str: + value = record.get(field) + if not isinstance(value, str) or not value: + raise ValueError(f"{document_name} field {field} must be a non-empty string") + return value + + +def _validate_ui_alert(ui_alert: UiAlert) -> None: + for field_name in ("category", "display_name"): + value = getattr(ui_alert, field_name) + if not isinstance(value, str) or not value: + raise ValueError(f"UI alert {field_name} must be a non-empty string") + + +def _validate_api_type(api_type: ApiAlertType) -> None: + if not isinstance(api_type.api_id, int) or isinstance(api_type.api_id, bool): + raise ValueError("API type api_id must be an integer") + for field_name in ("name", "description", "category"): + value = getattr(api_type, field_name) + if not isinstance(value, str) or not value: + raise ValueError(f"API type {field_name} must be a non-empty string") + + +def load_ui_alerts(path: Path) -> list[UiAlert]: + """Load reviewed UI evidence without resolving it to API types.""" + + payload = _read_json(path, "UI alert manifest") + if not isinstance(payload, list): + raise ValueError("UI alert manifest must be a list") + + alerts: list[UiAlert] = [] + for record in payload: + if not isinstance(record, dict): + raise ValueError("UI alert manifest records must be objects") + api_match = record.get("api_match") + if api_match is not None and not isinstance(api_match, dict): + raise ValueError("UI alert manifest api_match must be an object") + alert = UiAlert( + category=_require_string(record, "category", "UI alert manifest"), + display_name=_require_string( + record, "display_name", "UI alert manifest" + ), + api_match=api_match, + ) + _validate_ui_alert(alert) + alerts.append(alert) + return alerts + + +def build_catalog( + ui_alerts: Sequence[UiAlert], + api_types: Sequence[ApiAlertType], +) -> list[CatalogEntry]: + """Join exact UI evidence to API definitions with no fuzzy matching.""" + + api_by_source: dict[str, ApiAlertType] = {} + for api_type in api_types: + _validate_api_type(api_type) + if api_type.name in api_by_source: + raise ValueError("duplicate API source type") + api_by_source[api_type.name] = api_type + + seen_ui_alerts: set[tuple[str, str]] = set() + used_sources: set[str] = set() + catalog: list[CatalogEntry] = [] + for ui_alert in ui_alerts: + _validate_ui_alert(ui_alert) + ui_key = (ui_alert.category, ui_alert.display_name.casefold()) + if ui_key in seen_ui_alerts: + raise ValueError("duplicate UI alert") + seen_ui_alerts.add(ui_key) + + if ui_alert.api_match is not None: + api_type = _resolve_approved_override(ui_alert, api_by_source) + name_match = "approved_difference" + else: + api_type = _resolve_exact_match(ui_alert, api_types) + name_match = "exact" + + if api_type.name in used_sources: + raise ValueError("duplicate API source type selected by UI alerts") + used_sources.add(api_type.name) + catalog.append( + CatalogEntry( + api_id=api_type.api_id, + source_type=api_type.name, + api_display_name=api_type.description, + display_name=ui_alert.display_name, + category=ui_alert.category, + name_match=name_match, + ) + ) + + return sorted(catalog, key=lambda entry: entry.source_type) + + +def _resolve_exact_match( + ui_alert: UiAlert, + api_types: Sequence[ApiAlertType], +) -> ApiAlertType: + description_matches = [ + api_type + for api_type in api_types + if api_type.description.casefold() == ui_alert.display_name.casefold() + ] + category_matches = [ + api_type + for api_type in description_matches + if api_type.category == ui_alert.category + ] + if not category_matches: + if description_matches: + raise ValueError("category mismatch for UI alert") + raise ValueError("unmatched UI alert") + if len(category_matches) != 1: + raise ValueError("ambiguous API match for UI alert") + return category_matches[0] + + +def _resolve_approved_override( + ui_alert: UiAlert, + api_by_source: Mapping[str, ApiAlertType], +) -> ApiAlertType: + assert ui_alert.api_match is not None + override = ui_alert.api_match + source_type = override.get("source_type") + api_display_name = override.get("api_display_name") + reason = override.get("reason") + if ( + not isinstance(source_type, str) + or not isinstance(api_display_name, str) + or reason != APPROVED_DIFFERENCE_REASON + ): + raise ValueError("approved override is malformed") + api_type = api_by_source.get(source_type) + if api_type is None: + raise ValueError("approved override has no matching API source type") + if ( + api_type.description != api_display_name + or api_type.category != ui_alert.category + or api_type.description == ui_alert.display_name + ): + raise ValueError("approved override does not match API evidence") + return api_type + + +def load_catalog(path: Path) -> dict[str, CatalogEntry]: + """Load a strict catalog keyed by exact raw API source type.""" + + payload = _read_json(path, "catalog") + if not isinstance(payload, list): + raise ValueError("catalog must be a list") + + catalog: dict[str, CatalogEntry] = {} + required_fields = ( + "api_id", + "source_type", + "api_display_name", + "display_name", + "category", + "name_match", + ) + for record in payload: + if not isinstance(record, dict): + raise ValueError("catalog records must be objects") + if any(field not in record for field in required_fields): + raise ValueError("catalog record is missing required fields") + api_id = record["api_id"] + if not isinstance(api_id, int) or isinstance(api_id, bool): + raise ValueError("catalog api_id must be an integer") + values = { + field: _require_string(record, field, "catalog") + for field in required_fields + if field != "api_id" + } + if values["name_match"] not in NAME_MATCHES: + raise ValueError("catalog name_match must be exact or approved_difference") + entry = CatalogEntry(api_id=api_id, **values) + if entry.source_type in catalog: + raise ValueError("catalog contains a duplicate source_type") + catalog[entry.source_type] = entry + return catalog + + +def resolve_alert( + source_type: str, + catalog: Mapping[str, CatalogEntry], + live_types: Sequence[ApiAlertType] | None = None, +) -> ResolvedAlert: + """Resolve a raw source type without guessing or printing warnings.""" + + if not isinstance(source_type, str) or not source_type: + raise ValueError("source_type must be a non-empty string") + + catalog_entry = catalog.get(source_type) + if catalog_entry is not None: + return ResolvedAlert( + source_type=source_type, + display_name=catalog_entry.display_name, + category=catalog_entry.category, + api_display_name=catalog_entry.api_display_name, + api_id=catalog_entry.api_id, + name_match=catalog_entry.name_match, + api_only=False, + unmapped=False, + warning_code=None, + ) + + live_matches = ( + [api_type for api_type in live_types if api_type.name == source_type] + if live_types is not None + else [] + ) + if len(live_matches) == 1: + api_type = live_matches[0] + return ResolvedAlert( + source_type=source_type, + display_name=api_type.description, + category=api_type.category, + api_display_name=api_type.description, + api_id=api_type.api_id, + name_match=None, + api_only=True, + unmapped=False, + warning_code="api_only_alert", + ) + + return _unmapped_alert(source_type, warning_code="unmapped_alert") + + +def _unmapped_alert(source_type: str, warning_code: str) -> ResolvedAlert: + return ResolvedAlert( + source_type=source_type, + display_name=source_type, + category=None, + api_display_name=None, + api_id=None, + name_match=None, + api_only=False, + unmapped=True, + warning_code=warning_code, + ) diff --git a/transition/alert-inventory/alert_inventory/classic_http.py b/transition/alert-inventory/alert_inventory/classic_http.py new file mode 100644 index 0000000..35e5480 --- /dev/null +++ b/transition/alert-inventory/alert_inventory/classic_http.py @@ -0,0 +1,316 @@ +"""One-attempt authenticated Classic Central GET and strict JSON decoding.""" + +from __future__ import annotations + +import json +import logging +import math +import ssl +import urllib.error +import urllib.parse +import urllib.request +from collections.abc import Callable, Sequence +from enum import Enum +from typing import Any + +import requests +from pycentral.classic.base import ArubaCentralBase, BearerAuth + +from alert_inventory.classic_types import ( + Credentials, + normalize_classic_central_origin, +) + + +class ClassicHTTPFailure(Enum): + HTTP = "http" + NETWORK = "network" + TLS = "tls" + RESPONSE = "response" + JSON = "json" + UNEXPECTED = "unexpected" + + +class ClassicHTTPError(RuntimeError): + """A Classic Central request failure with only safe retry facts.""" + + def __init__( + self, + kind: ClassicHTTPFailure, + *, + status_code: int | None = None, + retry_after: str | None = None, + ): + super().__init__("Classic Central GET request failed") + self.kind = kind + self.status_code = status_code + self.retry_after = retry_after + + +class _PyCentralClient(ArubaCentralBase): + def __init__(self, central_info: dict[str, Any], timeout: float): + super().__init__( + central_info, + logger=logging.getLogger("pycentral"), + ssl_verify=True, + user_retries=0, + ) + self._timeout = timeout + + def requestUrl( + self, + url, + data={}, + method="GET", + headers={}, + params={}, + files={}, + ): + request = requests.Request( + method=method, + url=url, + headers=headers, + files=files, + auth=BearerAuth(self.central_info["token"]["access_token"]), + params=params, + data=data, + ) + prepared = self.session.prepare_request(request) + settings = self.session.merge_environment_settings( + prepared.url, + {}, + None, + True, + None, + ) + return self.session.send( + prepared, + **settings, + timeout=self._timeout, + allow_redirects=False, + ) + + +def _validate_path(path: object) -> str: + error = "Classic Central API path must be an absolute path" + if ( + not isinstance(path, str) + or not path.startswith("/") + or path.startswith("//") + or "%" in path + or any(ord(character) < 32 or ord(character) == 127 for character in path) + ): + raise ValueError(error) + + try: + parsed = urllib.parse.urlsplit(path) + except ValueError: + raise ValueError(error) from None + + if ( + parsed.scheme + or parsed.netloc + or parsed.query + or parsed.fragment + or "?" in path + or "#" in path + or "\\" in path + ): + raise ValueError(error) + + segments = parsed.path[1:].split("/") + if any(segment in ("", ".", "..") for segment in segments): + raise ValueError(error) + + return parsed.path + + +def _validate_query(query: object) -> list[tuple[str, str]]: + error = "Classic Central query must contain string pairs" + try: + iterator = iter(query) + except TypeError: + raise ValueError(error) from None + + pairs: list[tuple[str, str]] = [] + for item in iterator: + if isinstance(item, (str, bytes)): + raise ValueError(error) + try: + key, value = item + except (TypeError, ValueError): + raise ValueError(error) from None + if not isinstance(key, str) or not isinstance(value, str): + raise ValueError(error) + pairs.append((key, value)) + + return pairs + + +def _exception_chain(exception: BaseException): + seen: set[int] = set() + pending = [exception] + while pending: + current = pending.pop() + if id(current) in seen: + continue + seen.add(id(current)) + yield current + + for related in ( + current.__cause__, + current.__context__, + current.reason if isinstance(current, urllib.error.URLError) else None, + ): + if isinstance(related, BaseException): + pending.append(related) + + +def _is_tls_failure(exception: BaseException) -> bool: + return any( + isinstance(related, (ssl.SSLError, requests.exceptions.SSLError)) + for related in _exception_chain(exception) + ) + + +def _classify_transport_failure(exception: BaseException) -> ClassicHTTPFailure: + if _is_tls_failure(exception): + return ClassicHTTPFailure.TLS + if any( + isinstance( + related, + ( + urllib.error.URLError, + TimeoutError, + ConnectionError, + requests.exceptions.Timeout, + requests.exceptions.ConnectionError, + ), + ) + for related in _exception_chain(exception) + ): + return ClassicHTTPFailure.NETWORK + return ClassicHTTPFailure.UNEXPECTED + + +def _retry_after_header(headers: object) -> str | None: + try: + value = headers.get("Retry-After") + except Exception: + return None + return value if isinstance(value, str) else None + + +def _http_error_facts(error: urllib.error.HTTPError) -> tuple[int | None, str | None]: + status_code = ( + error.code + if isinstance(error.code, int) and not isinstance(error.code, bool) + else None + ) + retry_after = _retry_after_header(error.headers) + return status_code, retry_after + + +def _reject_non_finite_json_number(_value: str) -> None: + raise ValueError + + +def get_json( + credentials: Credentials, + path: str, + query: Sequence[tuple[str, str]], + *, + opener: Callable[..., Any] | None = None, + timeout: float = 60, +) -> Any: + """Perform one authenticated Classic Central GET and decode strict JSON.""" + + if ( + not isinstance(timeout, (int, float)) + or isinstance(timeout, bool) + or not math.isfinite(timeout) + or timeout <= 0 + ): + raise ValueError("Classic Central timeout must be a finite positive number") + + validated_path = _validate_path(path) + validated_query = _validate_query(query) + base_url = normalize_classic_central_origin(credentials.base_url) + encoded_query = urllib.parse.urlencode(validated_query) + url = f"{base_url}{validated_path}" + if encoded_query: + url = f"{url}?{encoded_query}" + request = urllib.request.Request( + url, + headers={ + "Accept": "application/json", + "Authorization": f"Bearer {credentials.access_token}", + }, + method="GET", + ) + request.add_unredirected_header( + "Authorization", + f"Bearer {credentials.access_token}", + ) + + if opener is None: + def open_request(_request, *, timeout): + return _PyCentralClient( + { + "base_url": base_url, + "token": {"access_token": credentials.access_token}, + }, + timeout, + ).requestUrl(url, headers={"Accept": "application/json"}) + else: + open_request = opener + try: + with open_request(request, timeout=timeout) as response: + status = getattr( + response, + "status", + getattr(response, "status_code", None), + ) + if not isinstance(status, int) or isinstance(status, bool): + raise ClassicHTTPError(ClassicHTTPFailure.RESPONSE) + if status != 200: + raise ClassicHTTPError( + ClassicHTTPFailure.HTTP, + status_code=status, + retry_after=_retry_after_header( + getattr(response, "headers", None) + ), + ) + response_body = response.content if opener is None else response.read() + except ClassicHTTPError: + raise + except urllib.error.HTTPError as error: + status_code, retry_after = _http_error_facts(error) + try: + error.close() + except Exception: + pass + raise ClassicHTTPError( + ClassicHTTPFailure.HTTP, + status_code=status_code, + retry_after=retry_after, + ) from None + except Exception as error: + raise ClassicHTTPError(_classify_transport_failure(error)) from None + + try: + payload = json.loads( + response_body.decode("utf-8"), + parse_constant=_reject_non_finite_json_number, + ) + except ( + AttributeError, + TypeError, + UnicodeDecodeError, + json.JSONDecodeError, + ValueError, + RecursionError, + ): + raise ClassicHTTPError(ClassicHTTPFailure.JSON) from None + + return payload diff --git a/transition/alert-inventory/alert_inventory/classic_types.py b/transition/alert-inventory/alert_inventory/classic_types.py new file mode 100644 index 0000000..e19bfa3 --- /dev/null +++ b/transition/alert-inventory/alert_inventory/classic_types.py @@ -0,0 +1,322 @@ +"""Safe retrieval of Classic Central notification type definitions.""" + +from __future__ import annotations + +import ipaddress +import json +import os +import re +import secrets +import stat +import urllib.parse +from collections.abc import Callable +from dataclasses import dataclass, field +from pathlib import Path +from typing import Any + + +@dataclass(frozen=True) +class Credentials: + """Validated credentials for a Classic Central API request.""" + + base_url: str + access_token: str = field(repr=False) + + +@dataclass(frozen=True) +class ApiAlertType: + """The fields needed from a Classic Central notification type.""" + + api_id: int + name: str + description: str + category: str + + +def normalize_classic_central_origin(base_url: object) -> str: + error = "Classic Central base URL must be an HTTPS origin" + if not isinstance(base_url, str) or any( + ord(character) < 32 or ord(character) == 127 for character in base_url + ): + raise ValueError(error) + + try: + parsed = urllib.parse.urlsplit(base_url) + _ = parsed.port + hostname = parsed.hostname + except ValueError: + raise ValueError(error) from None + + hostname_is_valid = False + if hostname: + try: + ipaddress.ip_address(hostname) + except ValueError: + try: + ascii_hostname = ( + hostname.encode("idna").decode("ascii").removesuffix(".") + ) + except UnicodeError: + pass + else: + labels = ascii_hostname.split(".") + hostname_is_valid = ( + len(ascii_hostname) <= 253 + and all( + 0 < len(label) <= 63 + and label[0] != "-" + and label[-1] != "-" + and all( + character.isalnum() or character == "-" + for character in label + ) + for label in labels + ) + ) + else: + hostname_is_valid = True + + authority = parsed.netloc + authority_is_valid = re.fullmatch( + r"(?:\[[^\]]+\]|[^:]+)(?::[0-9]+)?", + authority, + ) + + if ( + parsed.scheme != "https" + or not hostname_is_valid + or parsed.username is not None + or parsed.password is not None + or parsed.path not in ("", "/") + or "?" in base_url + or "#" in base_url + or any(character.isspace() for character in base_url) + or authority_is_valid is None + ): + raise ValueError(error) + + return f"https://{authority}" + + +def load_credentials(path: Path) -> Credentials: + """Load an HTTPS credential file without exposing its token.""" + + try: + file_status = path.stat(follow_symlinks=False) + except OSError: + raise ValueError("token.json must be a readable regular file") from None + if not stat.S_ISREG(file_status.st_mode): + raise ValueError("token.json must be a regular file") + + try: + payload = json.loads(path.read_text(encoding="utf-8")) + except (OSError, json.JSONDecodeError) as exc: + raise ValueError("token.json must contain valid JSON") from exc + + if not isinstance(payload, dict): + raise ValueError("token.json must contain an object") + + base_url = payload.get("base_url") + token = payload.get("token") + access_token = token.get("access_token") if isinstance(token, dict) else None + base_url = normalize_classic_central_origin(base_url) + if not isinstance(access_token, str) or not access_token: + raise ValueError("token.access_token must be a non-empty string") + + return Credentials(base_url=base_url, access_token=access_token) + + +def cleanup_temp( + path: Path, + expected_stat: os.stat_result | None, +) -> None: + """Retry cleanup while the path still names the created file.""" + + for _ in range(3): + if expected_stat is not None: + try: + current_stat = path.stat(follow_symlinks=False) + except FileNotFoundError: + return + except OSError: + continue + if not os.path.samestat(expected_stat, current_stat): + return + try: + path.unlink() + return + except FileNotFoundError: + return + except OSError: + continue + + +def write_credentials(credentials: Credentials, path: Path) -> None: + """Atomically publish one canonical local credential file.""" + + if not isinstance(credentials, Credentials): + raise ValueError("token.json credentials were invalid") + base_url = normalize_classic_central_origin(credentials.base_url) + if ( + not isinstance(credentials.access_token, str) + or not credentials.access_token + ): + raise ValueError("token.json credentials were invalid") + try: + text = ( + json.dumps( + { + "base_url": base_url, + "token": {"access_token": credentials.access_token}, + }, + ensure_ascii=False, + indent=2, + allow_nan=False, + ) + + "\n" + ) + text.encode("utf-8") + except (TypeError, ValueError, UnicodeEncodeError): + raise ValueError("token.json credentials were invalid") from None + + destination = Path(path) + parent = destination.parent + temp_path: Path | None = None + temp_stat: os.stat_result | None = None + try: + if not parent.is_dir(): + raise OSError + try: + destination_stat = destination.stat(follow_symlinks=False) + except FileNotFoundError: + pass + else: + if not stat.S_ISREG(destination_stat.st_mode): + raise OSError + + for _ in range(100): + candidate = parent / ( + f".{destination.name}.{secrets.token_hex(8)}.tmp" + ) + try: + descriptor = os.open( + candidate, + os.O_WRONLY | os.O_CREAT | os.O_EXCL, + 0o600, + ) + except FileExistsError: + continue + temp_path = candidate + try: + temp_stat = os.fstat(descriptor) + if hasattr(os, "fchmod"): + os.fchmod(descriptor, 0o600) + with os.fdopen( + descriptor, + mode="w", + encoding="utf-8", + newline="\n", + ) as output: + descriptor = -1 + output.write(text) + output.flush() + os.fsync(output.fileno()) + finally: + if descriptor != -1: + os.close(descriptor) + break + else: + raise OSError + + os.replace(temp_path, destination) + temp_path = None + temp_stat = None + except OSError: + raise ValueError("token.json could not be saved") from None + finally: + if temp_path is not None: + cleanup_temp(temp_path, temp_stat) + + +def fetch_notification_types( + credentials: Credentials, + opener: Callable[..., Any] | None = None, +) -> list[ApiAlertType]: + """Retrieve all notification types using one GET-only request.""" + + from alert_inventory.classic_http import ( + ClassicHTTPError, + ClassicHTTPFailure, + get_json, + ) + try: + payload = get_json( + credentials, + "/central/v1/notifications/types", + ( + ("calculate_total", "true"), + ("limit", "1000"), + ("offset", "0"), + ), + opener=opener, + timeout=60, + ) + except ClassicHTTPError as exc: + if exc.kind is ClassicHTTPFailure.JSON: + raise ValueError( + "notification types response must contain valid JSON" + ) from None + raise RuntimeError("Classic Central notification types request failed") from None + + if not isinstance(payload, dict): + raise ValueError("notification types response must be a top-level object") + + records = payload.get("types") + count = payload.get("count") + total = payload.get("total") + if not isinstance(records, list): + raise ValueError("notification types response must contain a types list") + if ( + not isinstance(count, int) + or isinstance(count, bool) + or not isinstance(total, int) + or isinstance(total, bool) + or count != len(records) + or total != len(records) + ): + raise ValueError("notification types response must contain a complete result set") + + result: list[ApiAlertType] = [] + source_types: set[str] = set() + for record in records: + if not isinstance(record, dict): + raise ValueError("notification type records must be objects") + required_fields = ("id", "name", "desc", "category") + if any(field not in record for field in required_fields): + raise ValueError("notification type record is missing required fields") + api_id = record["id"] + name = record["name"] + description = record["desc"] + category = record["category"] + if not isinstance(api_id, int) or isinstance(api_id, bool): + raise ValueError("notification type record must have an integer id") + if not all( + isinstance(value, str) and value + for value in (name, description, category) + ): + raise ValueError( + "notification type name, description, and category must be non-empty strings" + ) + if name in source_types: + raise ValueError("notification types response contains a duplicate source type") + source_types.add(name) + result.append( + ApiAlertType( + api_id=api_id, + name=name, + description=description, + category=category, + ) + ) + + return result diff --git a/transition/alert-inventory/alert_inventory/classic_webhooks.py b/transition/alert-inventory/alert_inventory/classic_webhooks.py new file mode 100644 index 0000000..d7f6b70 --- /dev/null +++ b/transition/alert-inventory/alert_inventory/classic_webhooks.py @@ -0,0 +1,101 @@ +"""Best-effort retrieval of readable Classic Central webhook names.""" + +from __future__ import annotations + +import uuid +from collections.abc import Callable +from typing import Any + +from alert_inventory.classic_http import ( + ClassicHTTPError, + ClassicHTTPFailure, + get_json, +) +from alert_inventory.classic_types import Credentials + + +_WEBHOOKS_PATH = "/central/v1/webhooks" + + +class WebhookLookupError(RuntimeError): + """A sanitized one-attempt webhook index request failure.""" + + +def _canonical_webhook_id(value: object) -> str | None: + if not isinstance(value, str): + return None + try: + parsed = uuid.UUID(value) + except (ValueError, AttributeError): + return None + canonical = str(parsed) + return canonical if value.lower() == canonical else None + + +def parse_webhook_names(payload: Any) -> dict[str, str]: + """Validate a webhook index and return only its ID-to-name mapping.""" + + if not isinstance(payload, dict): + raise ValueError("webhooks response must be a top-level object") + + count = payload.get("count") + settings = payload.get("settings") + if ( + not isinstance(count, int) + or isinstance(count, bool) + or count < 0 + or not isinstance(settings, list) + or count != len(settings) + ): + raise ValueError("webhooks response must contain a complete result set") + + result: dict[str, str] = {} + for record in settings: + if not isinstance(record, dict): + raise ValueError("webhook records must be objects") + webhook_id = _canonical_webhook_id(record.get("wid")) + name = record.get("name") + if webhook_id is None: + raise ValueError("webhook record must have a canonical wid") + if not isinstance(name, str) or not name.strip(): + raise ValueError("webhook record must have a non-empty name") + if webhook_id in result: + raise ValueError("webhooks response contains a duplicate wid") + result[webhook_id] = name.strip() + + return result + + +def fetch_webhook_names( + credentials: Credentials, + opener: Callable[..., Any] | None = None, + *, + timeout: float = 60, +) -> dict[str, str]: + """Fetch the webhook index with one exact GET and no retries.""" + + try: + payload = get_json( + credentials, + _WEBHOOKS_PATH, + (), + opener=opener, + timeout=timeout, + ) + except ClassicHTTPError as exc: + if exc.kind is ClassicHTTPFailure.JSON: + raise ValueError( + "webhooks response must contain valid JSON" + ) from None + raise WebhookLookupError( + "Classic Central webhooks request failed" + ) from None + + return parse_webhook_names(payload) + + +__all__ = ( + "WebhookLookupError", + "fetch_webhook_names", + "parse_webhook_names", +) diff --git a/transition/alert-inventory/alert_inventory/cli.py b/transition/alert-inventory/alert_inventory/cli.py new file mode 100644 index 0000000..37e4982 --- /dev/null +++ b/transition/alert-inventory/alert_inventory/cli.py @@ -0,0 +1,77 @@ +"""Customer-facing Classic Central alert extraction command.""" + +from __future__ import annotations + +import argparse +import sys +from collections.abc import Sequence +from pathlib import Path + +from alert_inventory.extraction_command import ( + ExtractionCommandError, + ExtractionSummary, + extract_to_file, +) + + +def _build_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser( + description="Extract Classic Central alerts." + ) + commands = parser.add_subparsers(dest="command", required=True) + extract = commands.add_parser( + "extract", + help="retrieve enabled alert settings into a JSON file", + ) + extract.add_argument( + "--output", + type=Path, + metavar="PATH", + help="write to PATH instead of the timestamped file in this directory", + ) + extract.add_argument( + "--overwrite", + action="store_true", + help="replace an existing --output file", + ) + return parser + + +def _print_summary(summary: ExtractionSummary) -> None: + print(f"Created: {summary.output_path}") + print(f"Schema version: {summary.schema_version}") + print(f"Reported total: {summary.reported_total}") + print(f"Retrieved: {summary.retrieved}") + print(f"Enabled: {summary.enabled}") + print(f"Disabled: {summary.disabled}") + for alert_type in summary.enabled_types: + print(f"Enabled type: {alert_type}") + print( + "Warning: The JSON contains sensitive customer configuration " + "and is not safe for public sharing." + ) + + +def main(argv: Sequence[str] | None = None) -> int: + """Run the requested Alert Inventory command.""" + + parser = _build_parser() + arguments = parser.parse_args(argv) + if arguments.overwrite and arguments.output is None: + parser.error("--overwrite requires --output") + + try: + summary = extract_to_file( + output=arguments.output, + overwrite=arguments.overwrite, + ) + except ExtractionCommandError: + print("Extraction failed.", file=sys.stderr) + return 1 + + _print_summary(summary) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/transition/alert-inventory/alert_inventory/completed_artifacts.py b/transition/alert-inventory/alert_inventory/completed_artifacts.py new file mode 100644 index 0000000..f3b39b2 --- /dev/null +++ b/transition/alert-inventory/alert_inventory/completed_artifacts.py @@ -0,0 +1,765 @@ +"""Completed Run artifact construction after successful extraction.""" + +from __future__ import annotations + +import csv +import io +import uuid +from collections.abc import Callable, Iterator, Mapping, Sequence +from dataclasses import dataclass +from datetime import datetime +from pathlib import Path +from typing import Any + +from alert_inventory.catalog import AlertResolver, load_catalog +from alert_inventory.classic_types import ApiAlertType +from alert_inventory.extractor import ExtractionResult, build_export + + +_NOT_PROVIDED = "not provided" +_SOURCE_TYPE_KEYS = frozenset({"type", "sourcetype", "alerttype"}) +_SCOPE_KEYS = frozenset({"scope", "scopetype", "level"}) +_SITE_NAME_KEYS = frozenset({"site", "sitename"}) +_GROUP_NAME_KEYS = frozenset( + {"group", "groupname", "devicegroup", "devicegroupname"} +) +_DEVICE_NAME_KEYS = frozenset( + {"devicename", "hostname", "targetname"} +) +_DEVICE_ID_KEYS = frozenset({"deviceid", "deviceuuid"}) +_SERIAL_KEYS = frozenset({"serial", "serialnumber"}) +_TARGET_KEYS = frozenset({"target", "targetname", "scopevalue"}) +_SEVERITY_KEYS = frozenset({"severity", "severities", "priority"}) +_CONDITION_KEYS = frozenset( + {"condition", "conditions", "criteria", "criterion", "rule", "rules"} +) +_DURATION_KEYS = frozenset( + { + "delay", + "duration", + "for", + "interval", + "timewindow", + "waittime", + "window", + } +) +_IDENTIFIER_KEYS = frozenset( + { + "id", + "settingid", + "siteid", + "groupid", + "devicegroupid", + "deviceid", + "deviceuuid", + "serial", + "serialnumber", + "mac", + "macaddress", + "labelid", + "policyid", + } +) +_NOTIFICATION_OPTION_KINDS = { + "webhook": "webhook", + "email": "email", + "streaming": "streaming", +} + + +def _key(value: object) -> str: + return ( + "".join(character for character in value if character.isalnum()).lower() + if isinstance(value, str) + else "" + ) + + +def _mappings(value: Any) -> Iterator[Mapping[str, Any]]: + pending = [value] + while pending: + current = pending.pop() + if isinstance(current, Mapping): + yield current + pending.extend(reversed(current.values())) + elif isinstance(current, list): + pending.extend(reversed(current)) + + +def _matched_values( + value: Any, + keys: frozenset[str], +) -> Iterator[Any]: + for mapping in _mappings(value): + for name, candidate in mapping.items(): + if _key(name) in keys: + yield candidate + + +def _scalar_text(value: Any) -> str | None: + if isinstance(value, str): + stripped = value.strip() + return stripped or None + if isinstance(value, bool): + return "true" if value else "false" + if isinstance(value, (int, float)): + return str(value) + return None + + +def _scalar_values(value: Any) -> Iterator[str]: + scalar = _scalar_text(value) + if scalar is not None: + yield scalar + return + if isinstance(value, list): + for item in value: + yield from _scalar_values(item) + return + if isinstance(value, Mapping): + preferred = ( + "name", + "label", + "displayname", + "description", + "url", + "address", + "value", + "id", + ) + normalized = {_key(key): child for key, child in value.items()} + for name in preferred: + if name in normalized: + yield from _scalar_values(normalized[name]) + + +def _unique(values: Iterator[str]) -> list[str]: + result = [] + seen = set() + for value in values: + if value not in seen: + seen.add(value) + result.append(value) + return result + + +def _text_values(value: Any, keys: frozenset[str]) -> list[str]: + return _unique( + text + for candidate in _matched_values(value, keys) + for text in _scalar_values(candidate) + ) + + +def _top_level_text( + setting: Mapping[str, Any], + keys: frozenset[str], +) -> str | None: + for name, value in setting.items(): + if _key(name) in keys: + return next(_scalar_values(value), None) + return None + + +def _first_text(value: Any, keys: frozenset[str]) -> str | None: + values = _text_values(value, keys) + return values[0] if values else None + + +def _measurement(value: Any) -> str | None: + scalar = _scalar_text(value) + if scalar is not None: + return scalar + if not isinstance(value, Mapping): + return None + normalized = {_key(key): child for key, child in value.items()} + amount = next( + ( + _scalar_text(normalized[name]) + for name in ("value", "threshold", "amount") + if name in normalized and _scalar_text(normalized[name]) is not None + ), + None, + ) + unit = next( + ( + _scalar_text(normalized[name]) + for name in ("unit", "units") + if name in normalized and _scalar_text(normalized[name]) is not None + ), + None, + ) + if amount and unit: + return f"{amount} {unit}" + return amount or unit + + +def _condition(value: Any) -> list[str]: + if isinstance(value, list): + return [ + text + for item in value + for text in _condition(item) + ] + scalar = _scalar_text(value) + if scalar is not None: + return [scalar] + if not isinstance(value, Mapping): + return [] + normalized = {_key(key): child for key, child in value.items()} + description = next( + ( + _scalar_text(normalized[name]) + for name in ("description", "text", "condition", "label") + if name in normalized and _scalar_text(normalized[name]) is not None + ), + None, + ) + if description: + return [description] + field = next( + ( + _scalar_text(normalized[name]) + for name in ("field", "metric", "name", "key") + if name in normalized and _scalar_text(normalized[name]) is not None + ), + None, + ) + operator = next( + ( + _scalar_text(normalized[name]) + for name in ("operator", "comparator", "comparison") + if name in normalized and _scalar_text(normalized[name]) is not None + ), + None, + ) + threshold = next( + ( + _measurement(normalized[name]) + for name in ("value", "threshold") + if name in normalized and _measurement(normalized[name]) is not None + ), + None, + ) + unit = next( + ( + _scalar_text(normalized[name]) + for name in ("unit", "units") + if name in normalized and _scalar_text(normalized[name]) is not None + ), + None, + ) + parts = [part for part in (field, operator, threshold, unit) if part] + return [" ".join(parts)] if parts else [] + + +def _conditions(setting: Mapping[str, Any]) -> list[str]: + return _unique( + text + for candidate in _matched_values(setting, _CONDITION_KEYS) + for text in _condition(candidate) + ) + + +def _duration(setting: Mapping[str, Any]) -> str | None: + for candidate in _matched_values(setting, _DURATION_KEYS): + value = _measurement(candidate) + if value: + return value + return None + + +def _rule_notification_options( + rule: Mapping[str, Any], + webhook_names: Mapping[str, str] | None, +) -> tuple[list[dict[str, Any]], int]: + options: list[dict[str, Any]] = [] + unresolved_references = 0 + + delivery_options = rule.get("delivery_options") + if not isinstance(delivery_options, list) or not all( + isinstance(option, str) for option in delivery_options + ): + return options, unresolved_references + + for source_option in delivery_options: + kind = _NOTIFICATION_OPTION_KINDS.get( + source_option.strip().casefold() + ) + if kind == "webhook": + targets = [] + webhooks = rule.get("webhooks") + if isinstance(webhooks, list): + for raw_target in webhooks: + if not isinstance(raw_target, str): + continue + target = raw_target.strip() + if not target: + continue + try: + canonical = str(uuid.UUID(target)) + except ValueError: + targets.append(target) + continue + if target.lower() != canonical: + targets.append(target) + continue + name = (webhook_names or {}).get(canonical) + if name is None: + unresolved_references += 1 + continue + targets.append(name) + options.append({"kind": kind, "targets": targets}) + elif kind == "email": + emails = rule.get("emails") + targets = _unique( + email.strip() + for email in emails + if isinstance(email, str) and email.strip() + ) if isinstance(emails, list) else [] + options.append({"kind": kind, "targets": targets}) + elif kind == "streaming": + options.append({"kind": kind, "targets": []}) + return options, unresolved_references + + +def _rule_conditions(rule: Mapping[str, Any]) -> list[dict[str, str | None]]: + conditions = rule.get("conditions") + if not isinstance(conditions, list): + return [] + + normalized_conditions = [] + for condition in conditions: + if not isinstance(condition, Mapping): + continue + severity = _scalar_text(condition.get("severity")) + if severity is None: + continue + expression = condition.get("expression") + operator = ( + _scalar_text(expression.get("operator")) + if isinstance(expression, Mapping) + else None + ) + value = ( + _scalar_text(expression.get("value")) + if isinstance(expression, Mapping) + else None + ) + normalized_conditions.append( + { + "severity": severity, + "operator": operator, + "value": value, + } + ) + return normalized_conditions + + +def _rule_duration(rule: Mapping[str, Any]) -> str | None: + for name, value in rule.items(): + if _key(name) not in _DURATION_KEYS: + continue + duration = _measurement(value) + if duration is not None: + return duration + return None + + +def _structured_rules( + setting: Mapping[str, Any], + webhook_names: Mapping[str, str] | None, +) -> tuple[list[dict[str, Any]], int]: + source_rules = setting.get("rules") + if not isinstance(source_rules, list): + return [], 0 + + rules = [] + unresolved_references = 0 + for number, source_rule in enumerate(source_rules): + if not isinstance(source_rule, Mapping): + continue + delivery_options, unresolved = _rule_notification_options( + source_rule, + webhook_names, + ) + rules.append( + { + "number": number, + "duration": _rule_duration(source_rule), + "deliveryOptions": delivery_options, + "conditions": _rule_conditions(source_rule), + } + ) + unresolved_references += unresolved + return rules, unresolved_references + + +def _canonical_scope(value: str | None) -> str | None: + if value is None: + return None + normalized = _key(value) + if "devicegroup" in normalized or normalized == "group": + return "device-group" + if normalized in {"device", "devices"}: + return "device" + if normalized in {"site", "sites"}: + return "site" + if normalized in {"global", "all", "allalerts"}: + return "global" + return None + + +def _explicit_scope( + setting: Mapping[str, Any], +) -> tuple[str | None, str | None]: + value = next( + ( + candidate + for name, candidate in setting.items() + if _key(name) in _SCOPE_KEYS + ), + None, + ) + if isinstance(value, Mapping): + normalized = {_key(name): child for name, child in value.items()} + scope = next( + ( + _canonical_scope(_scalar_text(normalized[name])) + for name in ("type", "scope", "level") + if name in normalized + and _canonical_scope(_scalar_text(normalized[name])) is not None + ), + None, + ) + name = next( + ( + _scalar_text(normalized[key]) + for key in ("name", "label", "target", "value") + if key in normalized + and _scalar_text(normalized[key]) is not None + ), + None, + ) + return scope, name + return _canonical_scope(_scalar_text(value)), None + + +def _identifier_values(setting: Mapping[str, Any]) -> dict[str, str]: + identifiers = {} + for mapping in _mappings(setting): + for name, value in mapping.items(): + if _key(name) not in _IDENTIFIER_KEYS: + continue + scalar = _scalar_text(value) + if scalar is not None and name not in identifiers: + identifiers[name] = scalar + return identifiers + + +def _alert_id( + setting: Mapping[str, Any], + identifiers: Mapping[str, str], + index: int, +) -> str: + for name, value in identifiers.items(): + if _key(name) in {"settingid", "id"}: + return value + return f"alert-{index + 1}" + + +def _normalize_setting( + setting: Mapping[str, Any], + *, + index: int, + resolver: AlertResolver, + webhook_names: Mapping[str, str] | None = None, +) -> tuple[dict[str, Any], int]: + source_type = _top_level_text(setting, _SOURCE_TYPE_KEYS) + if source_type is None: + name = "Unmapped alert" + api_display_name = None + category = None + is_mapped = False + else: + resolution = resolver.resolve(source_type) + name = resolution.display_name + api_display_name = resolution.api_display_name + category = resolution.category + is_mapped = not resolution.unmapped + + scope, scope_name = _explicit_scope(setting) + site_name = _first_text(setting, _SITE_NAME_KEYS) + group_name = _first_text(setting, _GROUP_NAME_KEYS) + device_id = _first_text(setting, _DEVICE_ID_KEYS) + serial_number = _first_text(setting, _SERIAL_KEYS) + device_name = _first_text(setting, _DEVICE_NAME_KEYS) + explicit_target = _first_text(setting, _TARGET_KEYS) + if scope == "site": + site_name = site_name or scope_name + elif scope == "device-group": + group_name = group_name or scope_name + elif scope == "device": + device_name = device_name or scope_name + if scope is None: + if device_id or serial_number or device_name: + scope = "device" + elif group_name: + scope = "device-group" + elif site_name: + scope = "site" + else: + scope = "global" + + if scope == "site": + target = site_name or explicit_target or _NOT_PROVIDED + elif scope == "device-group": + target = group_name or explicit_target or _NOT_PROVIDED + elif scope == "device": + target = ( + device_name + or explicit_target + or serial_number + or device_id + or _NOT_PROVIDED + ) + else: + target = None + + identifiers = _identifier_values(setting) + severities = [ + value.lower() + for value in _text_values(setting, _SEVERITY_KEYS) + ] or [_NOT_PROVIDED] + rules, unresolved_references = _structured_rules( + setting, + webhook_names, + ) + notification_options = [ + option + for rule in rules + for option in rule["deliveryOptions"] + ] + + return { + "id": _alert_id(setting, identifiers, index), + "scope": scope, + "name": name, + "apiDisplayName": api_display_name, + "sourceType": source_type, + "category": category, + "severities": _unique(iter(severities)), + "notificationOptions": notification_options, + "rules": rules, + "target": target, + "conditions": _conditions(setting), + "duration": _duration(setting), + "siteName": site_name, + "deviceGroupName": group_name, + "deviceId": device_id, + "serialNumber": serial_number, + "identifiers": identifiers, + "isMapped": is_mapped, + }, unresolved_references + + +_CSV_HEADERS = ( + "Scope type", + "Scope", + "Alert", + "Category", + "Severity", + "Conditions", + "Duration", + "Notification options", +) +_CSV_SCOPE_LABELS = { + "global": "Global", + "site": "Site", + "device-group": "Device Group", + "device": "Device", +} + + +def _csv_text(value: object) -> str: + if value is None: + return "" + return value if isinstance(value, str) else str(value) + + +def _csv_list(value: object) -> str: + if not isinstance(value, list): + return "" + values = [text for item in value if (text := _csv_text(item))] + return "" if values == [_NOT_PROVIDED] else "; ".join(values) + + +def _csv_scope(alert: Mapping[str, Any]) -> str: + scope = alert.get("scope") + if scope == "global": + return "Global" + if scope == "site": + return _csv_text( + alert.get("siteName") or alert.get("target") or "Unnamed site" + ) + if scope == "device-group": + return _csv_text( + alert.get("deviceGroupName") + or alert.get("target") + or "Unnamed device group" + ) + if scope == "device": + return _csv_text( + alert.get("target") + or alert.get("serialNumber") + or alert.get("deviceId") + or "Unnamed device" + ) + return _csv_text(alert.get("target")) + + +def _csv_notification_options(alert: Mapping[str, Any]) -> str: + options = alert.get("notificationOptions") + if not isinstance(options, list): + return "" + cells = [] + for option in options: + if not isinstance(option, Mapping): + continue + kind = option.get("kind") + label = { + "webhook": "Webhook", + "email": "Email", + "streaming": "Streaming", + }.get(kind) + if label is None: + continue + targets = option.get("targets") + target_text = ( + ", ".join( + text + for target in targets + if (text := _csv_text(target)) + ) + if isinstance(targets, list) + else "" + ) + cells.append(f"{label}: {target_text}" if target_text else label) + return "; ".join(cells) + + +def _serialize_run_csv(run: Mapping[str, Any]) -> bytes: + stream = io.StringIO(newline="") + writer = csv.writer( + stream, + lineterminator="\r\n", + quoting=csv.QUOTE_ALL, + ) + writer.writerow(_CSV_HEADERS) + alerts = run.get("alerts") + if isinstance(alerts, list): + for alert in alerts: + if not isinstance(alert, Mapping): + continue + writer.writerow( + ( + _CSV_SCOPE_LABELS.get( + alert.get("scope"), + _csv_text(alert.get("scope")), + ), + _csv_scope(alert), + alert.get("name") + or alert.get("apiDisplayName") + or alert.get("sourceType"), + alert.get("category"), + _csv_list(alert.get("severities")), + _csv_list(alert.get("conditions")), + alert.get("duration"), + _csv_notification_options(alert), + ) + ) + return stream.getvalue().encode("utf-8-sig") + + +@dataclass(frozen=True) +class CompletedRun: + """The paired source export and review projection of one completed run.""" + + source_export: dict[str, Any] + review_projection: dict[str, Any] + + +class CompletedArtifactBuilder: + """Construct and serialize completed artifacts after a successful retrieval.""" + + def __init__(self, *, catalog_path: Path) -> None: + self._catalog = load_catalog(catalog_path) + + def build( + self, + result: ExtractionResult, + *, + cluster_name: str, + origin: str, + run_id: str, + extracted_at: datetime, + fetch_notification_types: Callable[[], Sequence[ApiAlertType]], + check_cancelled: Callable[[], None], + webhook_names: Mapping[str, str] | None = None, + webhook_lookup_failed: bool = False, + ) -> CompletedRun: + """Pair a lossless export with an optionally enriched projection.""" + + check_cancelled() + source_export = build_export(result, extracted_at=extracted_at) + resolver = AlertResolver( + self._catalog, + fetcher=fetch_notification_types, + ) + alerts = [] + reference_count = 0 + assignment_count = 0 + for index, setting in enumerate(result.enabled_settings): + check_cancelled() + alert, unresolved_references = _normalize_setting( + setting, + index=index, + resolver=resolver, + webhook_names=webhook_names, + ) + alerts.append(alert) + reference_count += unresolved_references + if unresolved_references: + assignment_count += 1 + check_cancelled() + notification_option_error = ( + { + "reason": ( + "lookup-failed" + if webhook_lookup_failed + else "unresolved-references" + ), + "referenceCount": reference_count, + "assignmentCount": assignment_count, + } + if reference_count + else None + ) + return CompletedRun( + source_export=source_export, + review_projection={ + "id": run_id, + "cluster": {"name": cluster_name, "origin": origin}, + "fetchedAt": source_export["source"]["extracted_at"], + "completionState": "complete", + "enabledAlertCount": len(alerts), + "alerts": alerts, + "notificationOptionError": notification_option_error, + }, + ) + + def serialize_csv(self, completed_run: CompletedRun) -> bytes: + """Serialize a Completed Run's review projection as the readable CSV.""" + + return _serialize_run_csv(completed_run.review_projection) diff --git a/transition/alert-inventory/alert_inventory/extraction_command.py b/transition/alert-inventory/alert_inventory/extraction_command.py new file mode 100644 index 0000000..a072c72 --- /dev/null +++ b/transition/alert-inventory/alert_inventory/extraction_command.py @@ -0,0 +1,110 @@ +"""Command-facing Classic Central extraction-to-file orchestration.""" + +from __future__ import annotations + +from dataclasses import dataclass +from datetime import datetime, timezone +from pathlib import Path + +from alert_inventory.classic_types import load_credentials +from alert_inventory.extractor import ( + ExtractionError, + build_export, + extract_settings, + write_export, +) + + +__all__ = ( + "ExtractionSummary", + "ExtractionCommandError", + "extract_to_file", +) + +_TOKEN_PATH = Path(__file__).resolve().parent.parent / "token.json" +_COMMAND_FAILED = "Classic Central alert settings extraction failed" + + +@dataclass(frozen=True) +class ExtractionSummary: + """Safe facts about one published schema-v1 extraction.""" + + output_path: Path + schema_version: int + reported_total: int + retrieved: int + enabled: int + disabled: int + enabled_types: tuple[str, ...] + + +class ExtractionCommandError(RuntimeError): + """A sanitized extraction-to-file failure safe for command output.""" + + pass + + +def _utc_now() -> datetime: + return datetime.now(timezone.utc) + + +def _terminal_safe(value: str) -> str: + escaped = [] + for character in value: + if character.isprintable(): + escaped.append(character) + continue + codepoint = ord(character) + if codepoint <= 0xFF: + escaped.append(f"\\x{codepoint:02x}") + elif codepoint <= 0xFFFF: + escaped.append(f"\\u{codepoint:04x}") + else: + escaped.append(f"\\U{codepoint:08x}") + return "".join(escaped) + + +def extract_to_file( + *, + output: Path | None = None, + overwrite: bool = False, +) -> ExtractionSummary: + """Retrieve enabled Classic settings and atomically publish schema v1.""" + + if overwrite and output is None: + raise ExtractionCommandError( + "overwrite requires an explicit output path" + ) + + try: + extracted_at = _utc_now().astimezone(timezone.utc) + destination = ( + Path(output) + if output is not None + else Path.cwd() + / ( + "classic-central-enabled-alert-configs-" + f"{extracted_at:%Y%m%dT%H%M%SZ}.json" + ) + ) + credentials = load_credentials(_TOKEN_PATH) + result = extract_settings(credentials) + document = build_export(result, extracted_at=extracted_at) + write_export(document, destination, overwrite=overwrite) + enabled_types = tuple( + _terminal_safe(alert_type) + for setting in result.enabled_settings + if isinstance((alert_type := setting.get("type")), str) + ) + return ExtractionSummary( + output_path=destination, + schema_version=document["schema_version"], + reported_total=result.reported_total, + retrieved=result.retrieved, + enabled=result.enabled, + disabled=result.disabled, + enabled_types=enabled_types, + ) + except (ExtractionError, OSError, RecursionError, ValueError): + command_error = ExtractionCommandError(_COMMAND_FAILED) + raise command_error diff --git a/transition/alert-inventory/alert_inventory/extractor.py b/transition/alert-inventory/alert_inventory/extractor.py new file mode 100644 index 0000000..6240af2 --- /dev/null +++ b/transition/alert-inventory/alert_inventory/extractor.py @@ -0,0 +1,419 @@ +"""Secure retrieval of Classic Central alert settings.""" + +from __future__ import annotations + +import json +import os +import secrets +import time +from collections.abc import Callable, Sequence +from dataclasses import dataclass +from datetime import datetime, timezone +from email.utils import parsedate_to_datetime +from pathlib import Path +from typing import Any + +from alert_inventory.classic_http import ( + ClassicHTTPError, + ClassicHTTPFailure, + get_json, +) +from alert_inventory.classic_types import ( + cleanup_temp, + Credentials, + normalize_classic_central_origin, +) + + +_REQUEST_FAILED = "Classic Central alert settings request failed" +_MALFORMED_RESPONSE = "Classic Central alert settings response was malformed" +_INVALID_RESPONSE = "Classic Central alert settings response was invalid" +_INVALID_PAGINATION = "Classic Central alert settings pagination was invalid" +_INVALID_BASE_URL = "Classic Central alert settings base URL was invalid" +_INVALID_TIMEOUT = "Classic Central alert settings timeout was invalid" +_EXPORT_SERIALIZATION_FAILED = "alert settings export serialization failed" +_EXPORT_WRITE_FAILED = "alert settings export write failed" +_DESTINATION_EXISTS = "alert settings export destination already exists" +_DESTINATION_IS_DIRECTORY = ( + "alert settings export destination is a directory" +) +_PARENT_MISSING = "alert settings export parent directory does not exist" +_SETTINGS_PATH = "/central/v1/notifications/settings" + + +@dataclass(frozen=True) +class ExtractionResult: + """Validated Classic Central alert settings retrieval.""" + + endpoint: str + reported_total: int + retrieved: int + enabled_settings: tuple[dict[str, Any], ...] + + @property + def enabled(self) -> int: + return len(self.enabled_settings) + + @property + def disabled(self) -> int: + return self.retrieved - self.enabled + + +class ExtractionError(RuntimeError): + """A sanitized alert settings extraction failure.""" + + def __init__( + self, + message: str, + *, + status_code: int | None = None, + ) -> None: + super().__init__(message) + self.status_code = status_code + + +class ExtractionCancelled(RuntimeError): + """An extraction was cancelled between synchronous transport requests.""" + + pass + + +def _raise_if_cancelled( + should_cancel: Callable[[], bool] | None, +) -> None: + if should_cancel is not None and should_cancel(): + raise ExtractionCancelled("Classic Central alert settings extraction cancelled") + + +def build_export( + result: ExtractionResult, + *, + extracted_at: datetime, +) -> dict[str, Any]: + """Build a schema-v1 export document from a validated retrieval.""" + + if extracted_at.tzinfo is None or extracted_at.utcoffset() is None: + raise ValueError("extracted_at must be timezone-aware") + timestamp = extracted_at.astimezone(timezone.utc).isoformat( + timespec="seconds" + ) + return { + "schema_version": 1, + "source": { + "endpoint": result.endpoint, + "extracted_at": timestamp.removesuffix("+00:00") + "Z", + }, + "counts": { + "reported_total": result.reported_total, + "retrieved": result.retrieved, + "enabled": result.enabled, + "disabled": result.disabled, + }, + "settings": list(result.enabled_settings), + } + + +def serialize_export(document: dict[str, Any]) -> str: + """Serialize an export deterministically as strict UTF-8 JSON text.""" + + try: + text = ( + json.dumps( + document, + ensure_ascii=False, + indent=2, + sort_keys=True, + allow_nan=False, + ) + + "\n" + ) + text.encode("utf-8") + return text + except (TypeError, ValueError, RecursionError, UnicodeEncodeError): + raise ExtractionError(_EXPORT_SERIALIZATION_FAILED) from None + + +def write_export( + document: dict[str, Any], + destination: Path, + *, + overwrite: bool = False, +) -> None: + """Write an export atomically without clobbering by default.""" + + text = serialize_export(document) + destination = Path(destination) + parent = destination.parent + temp_path: Path | None = None + temp_stat: os.stat_result | None = None + try: + if not parent.is_dir(): + raise ExtractionError(_PARENT_MISSING) + if destination.is_dir(): + raise ExtractionError(_DESTINATION_IS_DIRECTORY) + + for _ in range(100): + candidate = parent / ( + f".{destination.name}.{secrets.token_hex(8)}.tmp" + ) + try: + with candidate.open( + mode="x", + encoding="utf-8", + newline="\n", + ) as output: + temp_path = candidate + temp_stat = os.fstat(output.fileno()) + output.write(text) + output.flush() + os.fsync(output.fileno()) + break + except FileExistsError: + continue + else: + raise ExtractionError(_EXPORT_WRITE_FAILED) + + if overwrite: + os.replace(temp_path, destination) + temp_path = None + temp_stat = None + else: + try: + # The link is the no-clobber commit; cleanup cannot undo it. + os.link(temp_path, destination) + except FileExistsError: + raise ExtractionError(_DESTINATION_EXISTS) from None + except ExtractionError: + raise + except OSError: + raise ExtractionError(_EXPORT_WRITE_FAILED) from None + finally: + if temp_path is not None: + cleanup_temp(temp_path, temp_stat) + + +def _retry_after(retry_after: str | None, fallback: float) -> float: + if isinstance(retry_after, str): + if retry_after.isascii() and retry_after.isdigit(): + try: + seconds = int(retry_after) + except ValueError: + seconds = 60 + else: + try: + retry_at = parsedate_to_datetime(retry_after) + if retry_at.tzinfo is None: + retry_at = retry_at.replace(tzinfo=timezone.utc) + seconds = max( + 0, + (retry_at - datetime.now(timezone.utc)).total_seconds(), + ) + except Exception: + seconds = -1 + if seconds >= 0: + return min(float(seconds), 60) + return fallback + + +def _settings_request_error(error: ClassicHTTPError) -> ExtractionError: + if error.kind in ( + ClassicHTTPFailure.JSON, + ClassicHTTPFailure.RESPONSE, + ): + return ExtractionError(_MALFORMED_RESPONSE) + if ( + error.kind is ClassicHTTPFailure.HTTP + and isinstance(error.status_code, int) + and not isinstance(error.status_code, bool) + ): + return ExtractionError( + f"{_REQUEST_FAILED} (HTTP {error.status_code})", + status_code=error.status_code, + ) + return ExtractionError(_REQUEST_FAILED) + + +def _settings_input_error(error: ValueError) -> ExtractionError: + if str(error) == "Classic Central base URL must be an HTTPS origin": + return ExtractionError(_INVALID_BASE_URL) + if str(error) == "Classic Central timeout must be a finite positive number": + return ExtractionError(_INVALID_TIMEOUT) + raise error + + +def _request_json( + credentials: Credentials, + path: str, + query: Sequence[tuple[str, str]], + *, + opener: Callable[..., Any] | None, + sleep: Callable[[float], None], + timeout: float, + should_cancel: Callable[[], bool] | None, +) -> Any: + for attempt in range(4): + _raise_if_cancelled(should_cancel) + try: + return get_json( + credentials, + path, + query, + opener=opener, + timeout=timeout, + ) + except ValueError as exc: + raise _settings_input_error(exc) from None + except ClassicHTTPError as exc: + retryable_status = ( + exc.kind is ClassicHTTPFailure.HTTP + and exc.status_code is not None + and (exc.status_code == 429 or 500 <= exc.status_code <= 599) + ) + retryable_network = exc.kind is ClassicHTTPFailure.NETWORK + if attempt == 3 or not ( + retryable_status or retryable_network + ): + raise _settings_request_error(exc) from None + fallback = float(2**attempt) + delay = _retry_after(exc.retry_after, fallback) + _raise_if_cancelled(should_cancel) + sleep(delay) + + +def _canonical_json(value: Any) -> str: + try: + return json.dumps( + value, + ensure_ascii=False, + sort_keys=True, + separators=(",", ":"), + allow_nan=False, + ) + except (TypeError, ValueError, RecursionError): + raise ExtractionError(_INVALID_RESPONSE) from None + + +def _is_non_empty_identifier(value: Any) -> bool: + if value is None: + return False + if isinstance(value, (str, list, dict)): + return bool(value) + return True + + +def _validate_page( + payload: Any, + *, + expected_total: int | None, + accumulated: int, + seen_pages: set[str], + seen_setting_ids: set[str], +) -> tuple[list[dict[str, Any]], int]: + if not isinstance(payload, dict): + raise ExtractionError(_INVALID_RESPONSE) + + count = payload.get("count") + total = payload.get("total") + page = payload.get("settings") + if ( + not isinstance(count, int) + or isinstance(count, bool) + or count < 0 + or not isinstance(total, int) + or isinstance(total, bool) + or total < 0 + or not isinstance(page, list) + or count != len(page) + or any(not isinstance(setting, dict) for setting in page) + ): + raise ExtractionError(_INVALID_RESPONSE) + if expected_total is not None and total != expected_total: + raise ExtractionError(_INVALID_PAGINATION) + if accumulated + count > total: + raise ExtractionError(_INVALID_PAGINATION) + + fingerprint = _canonical_json(page) + if fingerprint in seen_pages: + raise ExtractionError(_INVALID_PAGINATION) + seen_pages.add(fingerprint) + + missing = object() + for setting in page: + setting_id = setting.get("setting_id", missing) + if setting_id is missing or not _is_non_empty_identifier(setting_id): + continue + canonical_id = _canonical_json(setting_id) + if canonical_id in seen_setting_ids: + raise ExtractionError(_INVALID_PAGINATION) + seen_setting_ids.add(canonical_id) + + if accumulated + count < total and count == 0: + raise ExtractionError(_INVALID_PAGINATION) + return page, total + + +def extract_settings( + credentials: Credentials, + *, + opener: Callable[..., Any] | None = None, + sleep: Callable[[float], None] = time.sleep, + timeout: float = 60, + should_cancel: Callable[[], bool] | None = None, + on_progress: Callable[[int, int], None] | None = None, +) -> ExtractionResult: + """Retrieve every enabled Classic alert setting in source order.""" + + try: + base_url = normalize_classic_central_origin(credentials.base_url) + except ValueError as exc: + raise _settings_input_error(exc) from None + endpoint = f"{base_url}{_SETTINGS_PATH}" + settings: list[dict[str, Any]] = [] + offset = 0 + reported_total: int | None = None + seen_pages: set[str] = set() + seen_setting_ids: set[str] = set() + + while reported_total is None or offset < reported_total: + _raise_if_cancelled(should_cancel) + query = ( + ("limit", "1000"), + ("offset", str(offset)), + ) + payload = _request_json( + credentials, + _SETTINGS_PATH, + query, + opener=opener, + sleep=sleep, + timeout=timeout, + should_cancel=should_cancel, + ) + + page, page_total = _validate_page( + payload, + expected_total=reported_total, + accumulated=offset, + seen_pages=seen_pages, + seen_setting_ids=seen_setting_ids, + ) + if reported_total is None: + reported_total = page_total + settings.extend(page) + offset += len(page) + if on_progress is not None: + on_progress(offset, reported_total) + _raise_if_cancelled(should_cancel) + + if reported_total is None or offset != reported_total: + raise ExtractionError(_INVALID_PAGINATION) + + enabled_settings = tuple( + setting for setting in settings if setting.get("active") is True + ) + return ExtractionResult( + endpoint=endpoint, + reported_total=reported_total, + retrieved=len(settings), + enabled_settings=enabled_settings, + ) diff --git a/transition/alert-inventory/alert_inventory/live_extraction.py b/transition/alert-inventory/alert_inventory/live_extraction.py new file mode 100644 index 0000000..f28d1b0 --- /dev/null +++ b/transition/alert-inventory/alert_inventory/live_extraction.py @@ -0,0 +1,703 @@ +"""In-memory lifecycle orchestration for live alert extraction.""" + +from __future__ import annotations + +import logging +import threading +import uuid +from collections.abc import Callable +from dataclasses import dataclass, field +from datetime import datetime, timezone +from pathlib import Path +from typing import Any + +from alert_inventory.completed_artifacts import ( + CompletedArtifactBuilder, + CompletedRun, +) +from alert_inventory.classic_webhooks import ( + WebhookLookupError, + fetch_webhook_names, +) +from alert_inventory.classic_types import ( + Credentials, + fetch_notification_types, + load_credentials, + write_credentials, +) +from alert_inventory.extractor import ( + ExtractionCancelled, + ExtractionError, + extract_settings, + serialize_export, +) + + +REVIEWED_CLUSTERS = { + "US-1": "https://app1-apigw.central.arubanetworks.com", + "US-2": "https://apigw-prod2.central.arubanetworks.com", + "US-East1": "https://apigw-us-east-1.central.arubanetworks.com", + "US-West4": "https://apigw-uswest4.central.arubanetworks.com", + "US-West5": "https://apigw-uswest5.central.arubanetworks.com", + "EU-1": "https://eu-apigw.central.arubanetworks.com", + "EU-Central2": "https://apigw-eucentral2.central.arubanetworks.com", + "EU-Central3": "https://apigw-eucentral3.central.arubanetworks.com", + "Canada-1": "https://apigw-ca.central.arubanetworks.com", + "China-1": "https://apigw.central.arubanetworks.com.cn", + "APAC-1": "https://api-ap.central.arubanetworks.com", + "APAC-EAST1": "https://apigw-apaceast.central.arubanetworks.com", + "APAC-SOUTH1": "https://apigw-apacsouth.central.arubanetworks.com", + "UAE-NORTH1": "https://apigw-uaenorth1.central.arubanetworks.com", + "Internal": "https://internal-apigw.central.arubanetworks.com", +} + + +class LiveExtractionError(Exception): + """A sanitized local extraction failure with its HTTP response facts.""" + + def __init__( + self, + status: int, + code: str, + message: str, + guidance: str | None = None, + ): + super().__init__(message) + self.status = status + self.code = code + self.message = message + self.guidance = guidance + + def payload(self) -> dict[str, str]: + body = {"code": self.code, "message": self.message} + if self.guidance is not None: + body["guidance"] = self.guidance + return body + + +def invalid_request() -> LiveExtractionError: + return LiveExtractionError( + 400, + "invalid_request", + "Select a reviewed cluster and enter an access token.", + ) + + +def _extraction_in_progress(action: str) -> LiveExtractionError: + return LiveExtractionError( + 409, + "extraction_in_progress", + "An extraction is already running.", + f"Wait for it to finish or cancel it before {action}.", + ) + + +def _extraction_not_found() -> LiveExtractionError: + return LiveExtractionError( + 404, + "extraction_not_found", + "This extraction is no longer available.", + "Start a new extraction.", + ) + + +def _completed_run_not_found() -> LiveExtractionError: + return LiveExtractionError( + 404, + "completed_run_not_found", + "This completed run is no longer available.", + "Start a new extraction.", + ) + + +def _utc_now() -> datetime: + return datetime.now(timezone.utc) + + +def _new_run_id() -> str: + return uuid.uuid4().hex + + +@dataclass(frozen=True) +class LiveExtractionDownload: + """A browser-ready artifact for one completed in-memory extraction.""" + + content: bytes + media_type: str + filename: str + + +_ACTIVE_JOB_STATES = frozenset( + {"validating_access", "fetching_enabled_alerts", "cancelling"} +) +_LOGGER = logging.getLogger(__name__) + + +def _download_filename(run_id: str, file_format: str) -> str: + safe_id = "".join( + character + if character.isascii() + and (character.isalnum() or character in {"-", "_"}) + else "-" + for character in run_id + ) + return f"classic-central-enabled-alerts-{safe_id or 'run'}.{file_format}" + + +@dataclass +class _ExtractionJob: + job_id: str + cluster_name: str + origin: str + credentials: Credentials | None = field(repr=False) + save_token: bool = False + cancellation: threading.Event = field(default_factory=threading.Event) + state: str = "validating_access" + retrieved: int = 0 + total: int | None = None + run: dict[str, Any] | None = None + failure: dict[str, object] | None = None + thread: threading.Thread | None = field(default=None, repr=False) + + +class LiveExtractionService: + """Run one observable, cancellable extraction and retain successful exports.""" + + def __init__( + self, + *, + catalog_path: Path, + opener: Callable[..., Any] | None = None, + sleep: Callable[[float], None] | None = None, + clock: Callable[[], datetime] = _utc_now, + job_id_factory: Callable[[], str] = _new_run_id, + run_id_factory: Callable[[], str] = _new_run_id, + request_timeout: float = 60, + credentials_path: Path | None = None, + ) -> None: + self._completed_artifacts = CompletedArtifactBuilder( + catalog_path=catalog_path + ) + self._opener = opener + self._sleep = sleep + self._clock = clock + self._job_id_factory = job_id_factory + self._run_id_factory = run_id_factory + self._request_timeout = request_timeout + self._credentials_path = ( + Path(credentials_path) + if credentials_path is not None + else Path(__file__).resolve().parent.parent / "token.json" + ) + self._completed_runs: dict[str, CompletedRun] = {} + self._latest_run_id: str | None = None + self._jobs: dict[str, _ExtractionJob] = {} + self._active_job_id: str | None = None + self._closed = False + self._lock = threading.RLock() + + @property + def completed_runs(self) -> list[dict[str, Any]]: + """Return completed runs newest first for this local process only.""" + + with self._lock: + return [ + completed.review_projection + for completed in reversed(self._completed_runs.values()) + ] + + @property + def latest_run_id(self) -> str | None: + """Return the newest completed run ID for this local process.""" + + with self._lock: + return self._latest_run_id + + def completed_run(self, run_id: object) -> dict[str, Any]: + """Return one completed, normalized review run.""" + + with self._lock: + return self._completed_run(run_id).review_projection + + def download_completed_run( + self, + run_id: object, + file_format: object, + ) -> LiveExtractionDownload: + """Build a canonical JSON or readable CSV artifact for one run.""" + + if not isinstance(file_format, str) or file_format not in { + "csv", + "json", + }: + raise LiveExtractionError( + 404, + "download_format_not_found", + "This download format is not available.", + ) + with self._lock: + completed = self._completed_run(run_id) + if file_format == "json": + return LiveExtractionDownload( + content=serialize_export(completed.source_export).encode("utf-8"), + media_type="application/json", + filename=_download_filename(completed.review_projection["id"], "json"), + ) + return LiveExtractionDownload( + content=self._completed_artifacts.serialize_csv(completed), + media_type="text/csv; charset=utf-8", + filename=_download_filename(completed.review_projection["id"], "csv"), + ) + + def start( + self, + cluster_name: object, + access_token: object, + *, + save_token: bool = False, + ) -> dict[str, object]: + """Start the only permitted live extraction for this process.""" + + if not isinstance(save_token, bool): + raise invalid_request() + cluster, origin, credentials = self._credentials( + cluster_name, + access_token, + ) + with self._lock: + return self._start_locked( + cluster, + origin, + credentials, + save_token=save_token, + ) + + def saved_token_metadata(self) -> dict[str, object] | None: + """Return only the reviewed cluster associated with a saved token.""" + + try: + cluster, origin, _ = self._saved_credentials() + except LiveExtractionError: + return None + return {"cluster": {"name": cluster, "origin": origin}} + + def start_saved(self, cluster_name: object) -> dict[str, object]: + """Start a live extraction using the process-local saved credential.""" + + cluster, origin, credentials = self._saved_credentials() + if cluster_name != cluster: + raise invalid_request() + with self._lock: + return self._start_locked(cluster, origin, credentials) + + def get_status(self, job_id: object) -> dict[str, object]: + """Return safe, count-only state for one local extraction job.""" + + with self._lock: + return self._status(self._job(job_id)) + + def cancel(self, job_id: object) -> dict[str, object]: + """Request cooperative cancellation before a later request or retry.""" + + with self._lock: + job = self._job(job_id) + if job.state in _ACTIVE_JOB_STATES: + job.cancellation.set() + job.state = "cancelling" + return self._status(job) + + def retry(self, job_id: object) -> dict[str, object]: + """Restart a retryable failed job with its process-local credentials.""" + + with self._lock: + job = self._job(job_id) + if job.state != "failed" or not bool( + (job.failure or {}).get("retryable") + ) or job.credentials is None: + raise LiveExtractionError( + 409, + "retry_unavailable", + "This extraction cannot be retried.", + "Change credentials and start a new extraction.", + ) + self._ensure_no_active_job("retrying") + job.cancellation = threading.Event() + job.state = "validating_access" + job.retrieved = 0 + job.total = None + job.run = None + job.failure = None + self._start_thread_locked(job) + return self._status(job) + + def shutdown(self, timeout: float = 0) -> None: + """Stop accepting jobs and cancel work that has not reached a request.""" + + with self._lock: + self._closed = True + active_threads = [] + for job in self._jobs.values(): + if job.state in _ACTIVE_JOB_STATES: + job.cancellation.set() + job.state = "cancelling" + if job.thread is not None: + active_threads.append(job.thread) + for thread in active_threads: + if thread is not threading.current_thread(): + thread.join(timeout=max(0, timeout)) + + def _credentials( + self, + cluster_name: object, + access_token: object, + ) -> tuple[str, str, Credentials]: + origin = ( + REVIEWED_CLUSTERS.get(cluster_name) + if isinstance(cluster_name, str) + else None + ) + if origin is None: + raise invalid_request() + if not isinstance(access_token, str) or not access_token: + raise invalid_request() + return cluster_name, origin, Credentials(origin, access_token) + + def _saved_credentials(self) -> tuple[str, str, Credentials]: + try: + credentials = load_credentials(self._credentials_path) + except ValueError: + raise invalid_request() from None + for cluster_name, origin in REVIEWED_CLUSTERS.items(): + if credentials.base_url == origin: + return cluster_name, origin, credentials + raise invalid_request() + + def _start_locked( + self, + cluster_name: str, + origin: str, + credentials: Credentials, + *, + save_token: bool = False, + ) -> dict[str, object]: + if self._closed: + raise _extraction_in_progress("starting another extraction") + self._ensure_no_active_job() + job = _ExtractionJob( + job_id=self._job_id_factory(), + cluster_name=cluster_name, + origin=origin, + credentials=credentials, + save_token=save_token, + ) + self._jobs[job.job_id] = job + self._start_thread_locked(job) + return self._status(job) + + def _start_thread_locked(self, job: _ExtractionJob) -> None: + self._active_job_id = job.job_id + job.thread = threading.Thread( + target=self._run_job, + args=(job,), + name=f"classic-alert-extraction-{job.job_id}", + daemon=True, + ) + job.thread.start() + + def _ensure_no_active_job( + self, + action: str = "starting another extraction", + ) -> None: + if self._active_job_id is None: + return + active = self._jobs.get(self._active_job_id) + if active is not None and active.state in _ACTIVE_JOB_STATES: + raise _extraction_in_progress(action) + self._active_job_id = None + + def _job(self, job_id: object) -> _ExtractionJob: + job = self._jobs.get(job_id) if isinstance(job_id, str) else None + if job is None: + raise _extraction_not_found() + return job + + def _completed_run(self, run_id: object) -> CompletedRun: + completed = ( + self._completed_runs.get(run_id) + if isinstance(run_id, str) + else None + ) + if completed is None: + raise _completed_run_not_found() + return completed + + def _remember_completed_run(self, completed: CompletedRun) -> None: + run_id = completed.review_projection["id"] + self._completed_runs.pop(run_id, None) + self._completed_runs[run_id] = completed + self._latest_run_id = run_id + + @staticmethod + def _status(job: _ExtractionJob) -> dict[str, object]: + status: dict[str, object] = { + "id": job.job_id, + "state": job.state, + "retrieved": job.retrieved, + "total": job.total, + } + if job.state == "complete" and job.run is not None: + status["run"] = job.run + if job.state == "failed" and job.failure is not None: + status["failure"] = dict(job.failure) + return status + + def _run_job(self, job: _ExtractionJob) -> None: + credentials = job.credentials + if credentials is None: + self._finish_failed( + job, + { + "category": "unexpected", + "guidance": ( + "Try the extraction again. If it continues to fail, " + "check the connection and contact support." + ), + "retryable": True, + }, + ) + return + try: + completed = self._run_extraction( + job.cluster_name, + job.origin, + credentials, + should_cancel=job.cancellation.is_set, + on_progress=lambda retrieved, total: self._record_progress( + job, + retrieved, + total, + ), + sleep=self._cancel_aware_sleep(job), + ) + except ExtractionCancelled: + self._finish_cancelled(job) + except ExtractionError as error: + self._finish_failed(job, self._failure(error)) + except Exception: + self._finish_failed( + job, + { + "category": "unexpected", + "guidance": ( + "Try the extraction again. If it continues to fail, " + "check the connection and contact support." + ), + "retryable": True, + }, + ) + else: + with self._lock: + if job.cancellation.is_set(): + job.state = "cancelled" + job.credentials = None + else: + try: + if job.save_token: + write_credentials( + credentials, + self._credentials_path, + ) + except ValueError: + job.state = "failed" + job.failure = { + "category": "credential_storage", + "guidance": ( + "The access token could not be saved on this " + "device. Check local file access and start " + "again." + ), + "retryable": True, + } + else: + job.run = completed.review_projection + job.state = "complete" + self._remember_completed_run(completed) + job.credentials = None + self._clear_active_job(job) + + def _record_progress( + self, + job: _ExtractionJob, + retrieved: int, + total: int, + ) -> None: + with self._lock: + if job.cancellation.is_set(): + raise ExtractionCancelled( + "Classic Central alert settings extraction cancelled" + ) + job.state = "fetching_enabled_alerts" + job.retrieved = retrieved + job.total = total + + def _finish_cancelled(self, job: _ExtractionJob) -> None: + with self._lock: + job.state = "cancelled" + job.credentials = None + self._clear_active_job(job) + + def _finish_failed( + self, + job: _ExtractionJob, + failure: dict[str, object], + ) -> None: + with self._lock: + if job.cancellation.is_set(): + job.state = "cancelled" + job.credentials = None + else: + job.state = "failed" + job.failure = failure + if not bool(failure.get("retryable")): + job.credentials = None + self._clear_active_job(job) + + def _clear_active_job(self, job: _ExtractionJob) -> None: + if self._active_job_id == job.job_id: + self._active_job_id = None + + def _cancel_aware_sleep( + self, + job: _ExtractionJob, + ) -> Callable[[float], None]: + if self._sleep is not None: + return self._sleep + return job.cancellation.wait + + @staticmethod + def _check_cancelled( + should_cancel: Callable[[], bool] | None, + ) -> None: + if should_cancel is not None and should_cancel(): + raise ExtractionCancelled( + "Classic Central alert settings extraction cancelled" + ) + + def _run_extraction( + self, + cluster_name: str, + origin: str, + credentials: Credentials, + *, + should_cancel: Callable[[], bool] | None = None, + on_progress: Callable[[int, int], None] | None = None, + sleep: Callable[[float], None] | None = None, + ) -> CompletedRun: + extraction_options: dict[str, Any] = { + "opener": self._opener, + "timeout": self._request_timeout, + "should_cancel": should_cancel, + "on_progress": on_progress, + } + if sleep is not None: + extraction_options["sleep"] = sleep + result = extract_settings(credentials, **extraction_options) + webhook_names, webhook_lookup_failed = self._fetch_webhook_names( + credentials, + should_cancel, + ) + return self._completed_artifacts.build( + result, + cluster_name=cluster_name, + origin=origin, + run_id=self._run_id_factory(), + extracted_at=self._clock(), + fetch_notification_types=lambda: self._fetch_notification_types( + credentials, + should_cancel, + ), + check_cancelled=lambda: self._check_cancelled(should_cancel), + webhook_names=webhook_names, + webhook_lookup_failed=webhook_lookup_failed, + ) + + def _fetch_webhook_names( + self, + credentials: Credentials, + should_cancel: Callable[[], bool] | None, + ) -> tuple[dict[str, str], bool]: + self._check_cancelled(should_cancel) + try: + result = fetch_webhook_names( + credentials, + opener=self._opener, + timeout=self._request_timeout, + ) + except (WebhookLookupError, ValueError): + self._check_cancelled(should_cancel) + _LOGGER.warning( + "Classic Central webhook name lookup unavailable; " + "continuing without enrichment" + ) + return {}, True + self._check_cancelled(should_cancel) + return result, False + + def _fetch_notification_types( + self, + credentials: Credentials, + should_cancel: Callable[[], bool] | None, + ): + self._check_cancelled(should_cancel) + result = fetch_notification_types(credentials, opener=self._opener) + self._check_cancelled(should_cancel) + return result + + @staticmethod + def _failure(error: ExtractionError) -> dict[str, object]: + status = error.status_code + if status in {401, 403}: + return { + "category": "invalid_access", + "status": status, + "guidance": ( + "Enter a new access token and start another extraction." + ), + "retryable": False, + } + if status == 429: + return { + "category": "rate_limited", + "status": status, + "guidance": ( + "Wait a few minutes, then retry this extraction." + ), + "retryable": True, + } + if isinstance(status, int) and 500 <= status <= 599: + return { + "category": "service_unavailable", + "status": status, + "guidance": ( + "Classic Central is temporarily unavailable. Retry this " + "extraction." + ), + "retryable": True, + } + if isinstance(status, int) and not isinstance(status, bool): + return { + "category": "request_rejected", + "status": status, + "guidance": ( + "Check the selected cluster and access token, then start " + "a new extraction." + ), + "retryable": False, + } + return { + "category": "transport", + "guidance": ( + "Check the network connection, then retry this extraction." + ), + "retryable": True, + } diff --git a/transition/alert-inventory/alert_inventory/ui.py b/transition/alert-inventory/alert_inventory/ui.py new file mode 100644 index 0000000..4f46e72 --- /dev/null +++ b/transition/alert-inventory/alert_inventory/ui.py @@ -0,0 +1,253 @@ +"""Validated production UI assets and the loopback-only local service.""" + +from __future__ import annotations + +import argparse +import json +import sys +import webbrowser +from collections.abc import Sequence +from contextlib import asynccontextmanager +from pathlib import Path + +import uvicorn +from fastapi import FastAPI, Request +from fastapi.responses import FileResponse, JSONResponse, Response +from fastapi.staticfiles import StaticFiles + +from alert_inventory.live_extraction import ( + LiveExtractionError, + LiveExtractionService, + invalid_request, +) + + +__all__ = ( + "LocalUiError", + "create_app", + "launch_local_ui", + "main", + "validate_ui_assets", +) + +_REPOSITORY_ROOT = Path(__file__).resolve().parent.parent +_LOOPBACK_HOST = "127.0.0.1" +_MAX_CREDENTIAL_REQUEST_BYTES = 64 * 1024 +_ASSET_ACTION = ( + "UI assets are missing. Customers: restore or download a complete, " + "unmodified distribution containing `static/`. Maintainers: run " + "`npm --prefix frontend ci && npm --prefix frontend run build` and " + "commit `static/`." +) + + +class LocalUiError(RuntimeError): + """A local UI failure safe and useful to print at the command line.""" + + pass + + +def validate_ui_assets(repository_root: Path = _REPOSITORY_ROOT) -> Path: + """Return the production asset directory when its files are present.""" + + asset_root = Path(repository_root) / "static" + if not (asset_root / "index.html").is_file() or not ( + asset_root / "assets" + ).is_dir(): + raise LocalUiError(_ASSET_ACTION) + return asset_root + + +def create_app( + repository_root: Path = _REPOSITORY_ROOT, + *, + extraction_service: LiveExtractionService | None = None, +) -> FastAPI: + """Build the local application from committed UI assets.""" + + root = Path(repository_root) + asset_root = validate_ui_assets(root) + resolved_asset_root = asset_root.resolve() + index_path = asset_root / "index.html" + service = extraction_service or LiveExtractionService( + catalog_path=( + _REPOSITORY_ROOT + / "data" + / "classic-central-alert-catalog.json" + ), + credentials_path=root / "token.json", + ) + + @asynccontextmanager + async def extraction_lifespan(_app: FastAPI): + try: + yield + finally: + service.shutdown() + + app = FastAPI( + title="Alert Inventory", + docs_url=None, + redoc_url=None, + openapi_url=None, + lifespan=extraction_lifespan, + ) + app.state.live_extraction = service + app.mount( + "/assets", + StaticFiles(directory=asset_root / "assets"), + name="ui-assets", + ) + + @app.exception_handler(LiveExtractionError) + async def extraction_error(_request: Request, error: LiveExtractionError): + return JSONResponse(error.payload(), status_code=error.status) + + @app.post("/api/extractions", include_in_schema=False) + async def start_extraction(request: Request) -> JSONResponse: + try: + body = await request.body() + if len(body) > _MAX_CREDENTIAL_REQUEST_BYTES: + raise invalid_request() + payload = json.loads(body) + except (UnicodeDecodeError, json.JSONDecodeError, RecursionError): + raise invalid_request() from None + if not isinstance(payload, dict): + raise invalid_request() + source = payload.get("credentialSource") + cluster = payload.get("cluster") + if source == "entered-token": + if set(payload) != { + "credentialSource", + "cluster", + "token", + "saveToken", + }: + raise invalid_request() + status = service.start( + cluster, + payload.get("token"), + save_token=payload.get("saveToken"), + ) + elif source == "saved-token": + if set(payload) != {"credentialSource", "cluster"}: + raise invalid_request() + status = service.start_saved(cluster) + else: + raise invalid_request() + return JSONResponse(status, status_code=202) + + @app.get("/api/credentials/saved-token", include_in_schema=False) + async def saved_token_metadata() -> JSONResponse: + return JSONResponse({"savedToken": service.saved_token_metadata()}) + + @app.get("/api/extractions/runs", include_in_schema=False) + async def completed_runs() -> JSONResponse: + return JSONResponse( + { + "runs": service.completed_runs, + "latestRunId": service.latest_run_id, + } + ) + + @app.get( + "/api/extractions/runs/{run_id}/download/{file_format}", + include_in_schema=False, + ) + async def download_completed_run( + run_id: str, + file_format: str, + ) -> Response: + download = service.download_completed_run(run_id, file_format) + return Response( + content=download.content, + media_type=download.media_type, + headers={ + "Content-Disposition": ( + f'attachment; filename="{download.filename}"' + ) + }, + ) + + @app.get("/api/extractions/runs/{run_id}", include_in_schema=False) + async def completed_run(run_id: str) -> JSONResponse: + return JSONResponse(service.completed_run(run_id)) + + @app.get("/api/extractions/{job_id}", include_in_schema=False) + async def extraction_status(job_id: str) -> JSONResponse: + return JSONResponse(service.get_status(job_id)) + + @app.delete("/api/extractions/{job_id}", include_in_schema=False) + async def cancel_extraction(job_id: str) -> JSONResponse: + return JSONResponse(service.cancel(job_id), status_code=202) + + @app.post("/api/extractions/{job_id}/retry", include_in_schema=False) + async def retry_extraction(job_id: str) -> JSONResponse: + return JSONResponse(service.retry(job_id), status_code=202) + + @app.get("/", include_in_schema=False) + def index() -> FileResponse: + return FileResponse(index_path) + + @app.get("/{path:path}", include_in_schema=False) + def application_route(path: str) -> FileResponse: + static_path = (asset_root / path).resolve() + if ( + static_path.is_relative_to(resolved_asset_root) + and static_path.is_file() + ): + return FileResponse(static_path) + return FileResponse(index_path) + + return app + + +def launch_local_ui( + repository_root: Path = _REPOSITORY_ROOT, + *, + port: int | None = None, +) -> None: + """Open and run the production UI on a loopback port.""" + + app = create_app(repository_root) + config = uvicorn.Config( + app, + host=_LOOPBACK_HOST, + port=port or 0, + access_log=False, + log_level="warning", + ) + bound_socket = config.bind_socket() + try: + bound_socket.listen(config.backlog) + port = bound_socket.getsockname()[1] + url = f"http://{_LOOPBACK_HOST}:{port}/" + server = uvicorn.Server(config) + print(f"Local UI: {url}", flush=True) + webbrowser.open(url) + try: + server.run(sockets=[bound_socket]) + except KeyboardInterrupt: + pass + finally: + bound_socket.close() + + +def main(argv: Sequence[str] | None = None) -> int: + """Launch the production UI from the public module entry point.""" + + parser = argparse.ArgumentParser( + description="Launch the Alert Inventory UI." + ) + parser.add_argument("--port", type=int, help="Port for the local UI.") + arguments = parser.parse_args(argv) + try: + launch_local_ui(port=arguments.port) + except LocalUiError as error: + print(str(error), file=sys.stderr) + return 1 + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/transition/alert-inventory/data/classic-central-alert-catalog.json b/transition/alert-inventory/data/classic-central-alert-catalog.json new file mode 100644 index 0000000..9040c41 --- /dev/null +++ b/transition/alert-inventory/data/classic-central-alert-catalog.json @@ -0,0 +1,1002 @@ +[ + { + "api_display_name": "Aggregated Device Disconnections", + "api_id": 2100, + "category": "SITE", + "display_name": "Aggregated Device Disconnections", + "name_match": "exact", + "source_type": "AGGREGATED_DEVICE_DISCONNECTIONS" + }, + { + "api_display_name": "AP With Missing Radios", + "api_id": 1249, + "category": "ACCESS POINT", + "display_name": "AP With Missing Radios", + "name_match": "exact", + "source_type": "AP With Missing Radios" + }, + { + "api_display_name": "AP Disconnected", + "api_id": 4, + "category": "ACCESS POINT", + "display_name": "AP Disconnected", + "name_match": "exact", + "source_type": "AP disconnected" + }, + { + "api_display_name": "Airgroup Alerts", + "api_id": 1262, + "category": "ACCESS POINT", + "display_name": "Airgroup Alerts", + "name_match": "exact", + "source_type": "AP_AG_ALERTS" + }, + { + "api_display_name": "All AP Tunnels Down", + "api_id": 1258, + "category": "ACCESS POINT", + "display_name": "All AP Tunnels Down", + "name_match": "exact", + "source_type": "AP_ALL_TUNNELS_DOWN" + }, + { + "api_display_name": "Connected Clients Per AP", + "api_id": 1255, + "category": "ACCESS POINT", + "display_name": "Connected Clients Per AP", + "name_match": "exact", + "source_type": "AP_CONNECTED_CLIENTS" + }, + { + "api_display_name": "AP CPU Utilization", + "api_id": 1250, + "category": "ACCESS POINT", + "display_name": "AP CPU Utilization", + "name_match": "exact", + "source_type": "AP_CPU_OVER_UTILIZATION" + }, + { + "api_display_name": "AP Crash", + "api_id": 1260, + "category": "ACCESS POINT", + "display_name": "AP Crash", + "name_match": "exact", + "source_type": "AP_CRASH" + }, + { + "api_display_name": "AP DHCP Pool Consumption Alert", + "api_id": 1265, + "category": "ACCESS POINT", + "display_name": "AP DHCP Pool Consumption Alert", + "name_match": "exact", + "source_type": "AP_DHCP_POOL_CONSUMPTION_ALERT" + }, + { + "api_display_name": "AP Memory Utilization", + "api_id": 1251, + "category": "ACCESS POINT", + "display_name": "AP Memory Utilization", + "name_match": "exact", + "source_type": "AP_MEMORY_OVER_UTILIZATION" + }, + { + "api_display_name": "Radio Noise Floor", + "api_id": 1253, + "category": "ACCESS POINT", + "display_name": "Radio Noise Floor", + "name_match": "exact", + "source_type": "AP_RADIO_NOISE_FLOOR" + }, + { + "api_display_name": "Radio Non Wi-Fi Utilization", + "api_id": 1259, + "category": "ACCESS POINT", + "display_name": "Radio Non Wi-Fi Utilization", + "name_match": "exact", + "source_type": "AP_RADIO_NON_WIFI_OVER_UTILIZATION" + }, + { + "api_display_name": "Radio Channel Utilization", + "api_id": 1252, + "category": "ACCESS POINT", + "display_name": "Radio Channel Utilization", + "name_match": "exact", + "source_type": "AP_RADIO_OVER_UTILIZATION" + }, + { + "api_display_name": "AP Reboot", + "api_id": 1261, + "category": "ACCESS POINT", + "display_name": "AP Reboot", + "name_match": "exact", + "source_type": "AP_REBOOT" + }, + { + "api_display_name": "AP Routing Table Limit", + "api_id": 1263, + "category": "ACCESS POINT", + "display_name": "AP Routing Table Limit", + "name_match": "exact", + "source_type": "AP_ROUTE_TABLE_CAPACITY" + }, + { + "api_display_name": "AP Tunnel Down", + "api_id": 1257, + "category": "ACCESS POINT", + "display_name": "AP Tunnel Down", + "name_match": "exact", + "source_type": "AP_TUNNEL_DOWN" + }, + { + "api_display_name": "Radio Frames Retry Percent", + "api_id": 1256, + "category": "ACCESS POINT", + "display_name": "Radio Frames Retry Percent", + "name_match": "exact", + "source_type": "AP_TX_RETRY_PERCENT" + }, + { + "api_display_name": "Gateway Cellular Data Usage", + "api_id": 1511, + "category": "GATEWAY", + "display_name": "Gateway Cellular Data Usage", + "name_match": "exact", + "source_type": "CELLULAR_DATA_USAGE" + }, + { + "api_display_name": "CFG-SET advertisement failure", + "api_id": 1554, + "category": "GATEWAY", + "display_name": "CFG-SET Advertisement Failure", + "name_match": "exact", + "source_type": "CFG_SET_ADVERTISEMENT_FAILURE" + }, + { + "api_display_name": "802.1x authentication delay detected", + "api_id": 1422, + "category": "CONNECTIVITY", + "display_name": "802.1x Authentication Delay Detected", + "name_match": "exact", + "source_type": "CLARITY_802_DOT_1X_DELAY" + }, + { + "api_display_name": "802.1x authentication failure detected", + "api_id": 1423, + "category": "CONNECTIVITY", + "display_name": "802.1x Authentication Failure Detected", + "name_match": "exact", + "source_type": "CLARITY_802_DOT_1X_FAILURE" + }, + { + "api_display_name": "Association delay detected", + "api_id": 1406, + "category": "CONNECTIVITY", + "display_name": "Association Delay Detected", + "name_match": "exact", + "source_type": "CLARITY_ASSOC_DELAY" + }, + { + "api_display_name": "Association failure detected", + "api_id": 1407, + "category": "CONNECTIVITY", + "display_name": "Association Failure Detected", + "name_match": "exact", + "source_type": "CLARITY_ASSOC_FAILURE" + }, + { + "api_display_name": "Authentication delay detected", + "api_id": 1404, + "category": "CONNECTIVITY", + "display_name": "Authentication Delay Detected", + "name_match": "exact", + "source_type": "CLARITY_AUTH_DELAY" + }, + { + "api_display_name": "Authentication failure detected", + "api_id": 1405, + "category": "CONNECTIVITY", + "display_name": "Authentication Failure Detected", + "name_match": "exact", + "source_type": "CLARITY_AUTH_FAILURE" + }, + { + "api_display_name": "Captive portal delay detected", + "api_id": 1426, + "category": "CONNECTIVITY", + "display_name": "Captive Portal Delay Detected", + "name_match": "exact", + "source_type": "CLARITY_CAPTIVE_PORTAL_DELAY" + }, + { + "api_display_name": "Captive portal failure detected", + "api_id": 1427, + "category": "CONNECTIVITY", + "display_name": "Captive Portal Failure Detected", + "name_match": "exact", + "source_type": "CLARITY_CAPTIVE_PORTAL_FAILURE" + }, + { + "api_display_name": "DHCP delay detected", + "api_id": 1402, + "category": "CONNECTIVITY", + "display_name": "DHCP Delay Detected", + "name_match": "exact", + "source_type": "CLARITY_DHCP_DELAY" + }, + { + "api_display_name": "DHCP failure detected", + "api_id": 1403, + "category": "CONNECTIVITY", + "display_name": "DHCP Failure Detected", + "name_match": "exact", + "source_type": "CLARITY_DHCP_FAILURE" + }, + { + "api_display_name": "DNS delay detected", + "api_id": 1400, + "category": "CONNECTIVITY", + "display_name": "DNS Delay Detected", + "name_match": "exact", + "source_type": "CLARITY_DNS_DELAY" + }, + { + "api_display_name": "DNS failure detected", + "api_id": 1401, + "category": "CONNECTIVITY", + "display_name": "DNS Failure Detected", + "name_match": "exact", + "source_type": "CLARITY_DNS_FAILURE" + }, + { + "api_display_name": "MAC authentication delay detected", + "api_id": 1424, + "category": "CONNECTIVITY", + "display_name": "MAC Authentication Delay Detected", + "name_match": "exact", + "source_type": "CLARITY_MAC_AUTH_DELAY" + }, + { + "api_display_name": "MAC authentication failure detected", + "api_id": 1425, + "category": "CONNECTIVITY", + "display_name": "MAC Authentication Failure Detected", + "name_match": "exact", + "source_type": "CLARITY_MAC_AUTH_FAILURE" + }, + { + "api_display_name": "Wi-Fi security key-exchange delay detected", + "api_id": 1420, + "category": "CONNECTIVITY", + "display_name": "Wi-Fi Security Key-Exchange Delay Detected", + "name_match": "exact", + "source_type": "CLARITY_WPA_DELAY" + }, + { + "api_display_name": "Wi-Fi security key-exchange failure detected", + "api_id": 1421, + "category": "CONNECTIVITY", + "display_name": "Wi-Fi Security Key-Exchange Failure Detected", + "name_match": "exact", + "source_type": "CLARITY_WPA_FAILURE" + }, + { + "api_display_name": "Connected Clients Per VC", + "api_id": 1254, + "category": "ACCESS POINT", + "display_name": "Connected Clients Per VC", + "name_match": "exact", + "source_type": "CONNECTED_CLIENTS" + }, + { + "api_display_name": "BGP Neighbor Route Limit", + "api_id": 1358, + "category": "GATEWAY", + "display_name": "BGP Neighbor Route Limit", + "name_match": "exact", + "source_type": "CONTROLLER BGP NEIGHBOR ROUTE LIMIT" + }, + { + "api_display_name": "BGP Session", + "api_id": 1355, + "category": "GATEWAY", + "display_name": "BGP Session", + "name_match": "exact", + "source_type": "CONTROLLER BGP SESSION ERROR" + }, + { + "api_display_name": "Overlay Route Orchestrator Connection", + "api_id": 1359, + "category": "GATEWAY", + "display_name": "Overlay Route Orchestrator Connection", + "name_match": "exact", + "source_type": "CONTROLLER OAP CONNECTION" + }, + { + "api_display_name": "OSPF Session error", + "api_id": 1354, + "category": "GATEWAY", + "display_name": "OSPF Session Error", + "name_match": "exact", + "source_type": "CONTROLLER OSPF SESSION ERROR" + }, + { + "api_display_name": "Routing Table Limit", + "api_id": 1357, + "category": "GATEWAY", + "display_name": "Routing Table Limit", + "name_match": "exact", + "source_type": "CONTROLLER ROUTE TABLE CAPACITY" + }, + { + "api_display_name": "Gateway CPU Utilization", + "api_id": 1351, + "category": "GATEWAY", + "display_name": "Gateway CPU Utilization", + "name_match": "exact", + "source_type": "CONTROLLER_CPU_OVER_UTILIZATION" + }, + { + "api_display_name": "Gateway Emergency Mode", + "api_id": 1353, + "category": "GATEWAY", + "display_name": "Gateway Emergency Mode", + "name_match": "exact", + "source_type": "CONTROLLER_EMERGENCY_UP_LINK_MODE" + }, + { + "api_display_name": "Gateway Memory Utilization", + "api_id": 1352, + "category": "GATEWAY", + "display_name": "Gateway Memory Utilization", + "name_match": "exact", + "source_type": "CONTROLLER_MEMORY_OVER_UTILIZATION" + }, + { + "api_display_name": "Client Attack Detected", + "api_id": 13, + "category": "ACCESS POINT", + "display_name": "Client Attack Detected", + "name_match": "exact", + "source_type": "Client attack detected" + }, + { + "api_display_name": "Config change detected", + "api_id": 2000, + "category": "AUDIT", + "display_name": "Config Change Detected", + "name_match": "exact", + "source_type": "DEVICE_CONFIG_CHANGE_DETECTED" + }, + { + "api_display_name": "DHCP Pool Consumption Alert", + "api_id": 1510, + "category": "GATEWAY", + "display_name": "DHCP Pool Consumption Alert", + "name_match": "exact", + "source_type": "DHCP_POOL_CONSUMPTION_ALERT" + }, + { + "api_display_name": "DPP Attack", + "api_id": 1264, + "category": "ACCESS POINT", + "display_name": "DPP Attack", + "name_match": "exact", + "source_type": "DPP Attack" + }, + { + "api_display_name": "SLA DPS Compliance Violations", + "api_id": 20, + "category": "GATEWAY", + "display_name": "SLA DPS Compliance Violations", + "name_match": "exact", + "source_type": "DPS_COMPLIANCE_ALERT" + }, + { + "api_display_name": "EST enrollment failure", + "api_id": 1701, + "category": "GATEWAY", + "display_name": "EST Enrollment Failure", + "name_match": "exact", + "source_type": "EST enrollment failure" + }, + { + "api_display_name": "Existing App Uninstalled Alert", + "api_id": 3001, + "category": "IOT", + "display_name": "Existing App Uninstalled Alert", + "name_match": "exact", + "source_type": "EXISTING_APP_UNINSTALLED_ALERT" + }, + { + "api_display_name": "Existing Transport Profile Uninstalled Alert", + "api_id": 3003, + "category": "IOT", + "display_name": "Existing Transport Profile Uninstalled Alert", + "name_match": "exact", + "source_type": "EXISTING_TRANSPORT_PROFILE_UNINSTALLED_ALERT" + }, + { + "api_display_name": "Gateway Device Flash Memory Usage", + "api_id": 1512, + "category": "GATEWAY", + "display_name": "Gateway Device Flash/Memory Usage", + "name_match": "approved_difference", + "source_type": "FLASH_MEMORY_USAGE" + }, + { + "api_display_name": "Gateway base license capacity limit exceeded", + "api_id": 1356, + "category": "GATEWAY", + "display_name": "Gateway Base License Capacity Limit Exceeded", + "name_match": "exact", + "source_type": "GATEWAY_BASE_LICENSE_CAPACITY_EXCEEDED" + }, + { + "api_display_name": "Gateway Cluster Client Capacity", + "api_id": 1805, + "category": "GATEWAY", + "display_name": "Gateway Cluster Client Capacity", + "name_match": "exact", + "source_type": "GATEWAY_CLUSTER_CLIENT_CAPACITY_EXCEEDED" + }, + { + "api_display_name": "Gateway cluster leader change", + "api_id": 1804, + "category": "GATEWAY", + "display_name": "Gateway Cluster Leader Change", + "name_match": "exact", + "source_type": "GATEWAY_CLUSTER_LEADER_CHANGE" + }, + { + "api_display_name": "Gateway joining Cluster", + "api_id": 1802, + "category": "GATEWAY", + "display_name": "Gateway Joining Cluster", + "name_match": "exact", + "source_type": "GATEWAY_CONNECTED_TO_CLUSTER" + }, + { + "api_display_name": "Gateway Disconnected", + "api_id": 303, + "category": "GATEWAY", + "display_name": "Gateway Disconnected", + "name_match": "exact", + "source_type": "GATEWAY_DISCONNECTED" + }, + { + "api_display_name": "Gateway leaving Cluster", + "api_id": 1803, + "category": "GATEWAY", + "display_name": "Gateway Leaving Cluster", + "name_match": "exact", + "source_type": "GATEWAY_DISCONNECTED_FROM_CLUSTER" + }, + { + "api_display_name": "Gateway Cluster VLAN Mismatch", + "api_id": 1801, + "category": "GATEWAY", + "display_name": "Gateway Cluster VLAN Mismatch", + "name_match": "exact", + "source_type": "GW_CLUSTER_VLAN_MISMATCH" + }, + { + "api_display_name": "Gateway firmware upgrade failed", + "api_id": 2201, + "category": "GATEWAY", + "display_name": "Gateway Firmware Upgrade Failed", + "name_match": "exact", + "source_type": "GW_FW_UPGRADE_FAILURE" + }, + { + "api_display_name": "Gateway Threat count", + "api_id": 2305, + "category": "GATEWAY", + "display_name": "Gateway Threat Count", + "name_match": "exact", + "source_type": "GW_IDS_IPS_ALERT_THREAT_OVER_A_PERIOD" + }, + { + "api_display_name": "Gateway Threat count per signature", + "api_id": 2306, + "category": "GATEWAY", + "display_name": "Gateway Threat Count Per Signature", + "name_match": "exact", + "source_type": "GW_IDS_IPS_ALERT_THREAT_SID_OVER_A_PERIOD" + }, + { + "api_display_name": "Gateway Threat count per user", + "api_id": 2308, + "category": "GATEWAY", + "display_name": "Gateway Threat Count Per User", + "name_match": "exact", + "source_type": "GW_IDS_IPS_ALERT_THREAT_USER_OVER_A_PERIOD" + }, + { + "api_display_name": "Gateway IDS/IPS Engine CPU Utilization", + "api_id": 2302, + "category": "GATEWAY", + "display_name": "Gateway IDS/IPS Engine CPU Utilization", + "name_match": "exact", + "source_type": "GW_IDS_IPS_ENGINE_CPU_OVER_UTILIZATION" + }, + { + "api_display_name": "Gateway IDS/IPS Engine Error State", + "api_id": 2301, + "category": "GATEWAY", + "display_name": "Gateway IDS/IPS Engine Error State", + "name_match": "exact", + "source_type": "GW_IDS_IPS_ENGINE_ERROR_STATE_ALERT" + }, + { + "api_display_name": "Gateway IDS/IPS Engine Memory Utilization", + "api_id": 2303, + "category": "GATEWAY", + "display_name": "Gateway IDS/IPS Engine Memory Utilization", + "name_match": "exact", + "source_type": "GW_IDS_IPS_ENGINE_MEMORY_OVER_UTILIZATION" + }, + { + "api_display_name": "Gateway IDS/IPS Engine Packet Dropped Detected", + "api_id": 2304, + "category": "GATEWAY", + "display_name": "Gateway IDS/IPS Engine Packet Dropped Detected", + "name_match": "exact", + "source_type": "GW_IDS_IPS_ENGINE_PACKET_DROPPED_DETECTED" + }, + { + "api_display_name": "IAP Firmware Upgrade Failed", + "api_id": 2200, + "category": "ACCESS POINT", + "display_name": "IAP Firmware Upgrade Failed", + "name_match": "exact", + "source_type": "IAP_FW_UPGRADE_FAILURE" + }, + { + "api_display_name": "Insufficient Power Supplied", + "api_id": 21, + "category": "ACCESS POINT", + "display_name": "Insufficient Power Supplied", + "name_match": "exact", + "source_type": "INSUFFICIENT_POWER_ALERT" + }, + { + "api_display_name": "IPMS Pool Capacity Alert", + "api_id": 2501, + "category": "IP MANAGEMENT SYSTEM", + "display_name": "IPMS Pool Capacity Alert", + "name_match": "exact", + "source_type": "IPMS_POOL_CAPACITY_ALERT" + }, + { + "api_display_name": "Infrastructure Attack Detected", + "api_id": 12, + "category": "ACCESS POINT", + "display_name": "Infrastructure Attack Detected", + "name_match": "exact", + "source_type": "Infrastructure attack detected" + }, + { + "api_display_name": "Modem Plugged", + "api_id": 18, + "category": "ACCESS POINT", + "display_name": "Modem Plugged", + "name_match": "exact", + "source_type": "Modem Plugged" + }, + { + "api_display_name": "Modem Unplugged", + "api_id": 19, + "category": "ACCESS POINT", + "display_name": "Modem Unplugged", + "name_match": "exact", + "source_type": "Modem Unplugged" + }, + { + "api_display_name": "New App Installed Alert", + "api_id": 3000, + "category": "IOT", + "display_name": "New App Installed Alert", + "name_match": "exact", + "source_type": "NEW_APP_INSTALLED_ALERT" + }, + { + "api_display_name": "New Gateway Connected", + "api_id": 301, + "category": "GATEWAY", + "display_name": "New Gateway Connected", + "name_match": "exact", + "source_type": "NEW_GATEWAY_DETECTED" + }, + { + "api_display_name": "New Transport Profile Installed Alert", + "api_id": 3002, + "category": "IOT", + "display_name": "New Transport Profile Installed Alert", + "name_match": "exact", + "source_type": "NEW_TRANSPORT_PROFILE_INSTALLED_ALERT" + }, + { + "api_display_name": "New AP Detected", + "api_id": 3, + "category": "ACCESS POINT", + "display_name": "New AP Detected", + "name_match": "exact", + "source_type": "New AP detected" + }, + { + "api_display_name": "New Switch Connected", + "api_id": 201, + "category": "SWITCH", + "display_name": "New Switch Connected", + "name_match": "exact", + "source_type": "New Switch Connected" + }, + { + "api_display_name": "New User account added", + "api_id": 14, + "category": "USER", + "display_name": "New User Account Added", + "name_match": "exact", + "source_type": "New User account added" + }, + { + "api_display_name": "New Virtual Controller Detected", + "api_id": 1, + "category": "ACCESS POINT", + "display_name": "New Virtual Controller Detected", + "name_match": "exact", + "source_type": "New Virtual Controller detected" + }, + { + "api_display_name": "Rogue AP Detected", + "api_id": 10, + "category": "ACCESS POINT", + "display_name": "Rogue AP Detected", + "name_match": "exact", + "source_type": "Rogue AP detected" + }, + { + "api_display_name": "Switch CPU Utilization", + "api_id": 1300, + "category": "SWITCH", + "display_name": "Switch CPU Utilization", + "name_match": "exact", + "source_type": "SWITCH_CPU_OVER_UTILIZATION" + }, + { + "api_display_name": "Switch Hardware Failure", + "api_id": 207, + "category": "SWITCH", + "display_name": "Switch Hardware Failure", + "name_match": "exact", + "source_type": "SWITCH_HARDWARE_FAILURE" + }, + { + "api_display_name": "Switch Port Duplex Mode", + "api_id": 1306, + "category": "SWITCH", + "display_name": "Switch Port Duplex Mode", + "name_match": "exact", + "source_type": "SWITCH_INTERFACE_DUPLEX_MODE" + }, + { + "api_display_name": "Switch Port Input errors", + "api_id": 1304, + "category": "SWITCH", + "display_name": "Switch Port Input Errors", + "name_match": "exact", + "source_type": "SWITCH_INTERFACE_INPUT_ERRORS" + }, + { + "api_display_name": "Switch Port Output errors", + "api_id": 1305, + "category": "SWITCH", + "display_name": "Switch Port Output Errors", + "name_match": "exact", + "source_type": "SWITCH_INTERFACE_OUTPUT_ERRORS" + }, + { + "api_display_name": "Switch Port Rx Rate", + "api_id": 1303, + "category": "SWITCH", + "display_name": "Switch Port Rx Rate", + "name_match": "exact", + "source_type": "SWITCH_INTERFACE_RX_RATE" + }, + { + "api_display_name": "Switch Port Tx Rate", + "api_id": 1302, + "category": "SWITCH", + "display_name": "Switch Port Tx Rate", + "name_match": "exact", + "source_type": "SWITCH_INTERFACE_TX_RATE" + }, + { + "api_display_name": "Switch Memory Utilization", + "api_id": 1301, + "category": "SWITCH", + "display_name": "Switch Memory Utilization", + "name_match": "exact", + "source_type": "SWITCH_MEMORY_OVER_UTILIZATION" + }, + { + "api_display_name": "Switch PoE Utilization", + "api_id": 1307, + "category": "SWITCH", + "display_name": "Switch PoE Utilization", + "name_match": "exact", + "source_type": "SWITCH_POE_UTILIZATION" + }, + { + "api_display_name": "Switch Reboot", + "api_id": 1312, + "category": "SWITCH", + "display_name": "Switch Reboot", + "name_match": "exact", + "source_type": "SWITCH_REBOOT" + }, + { + "api_display_name": "Switch Stack Conductor Change", + "api_id": 1310, + "category": "SWITCH", + "display_name": "Switch Stack Conductor Change", + "name_match": "exact", + "source_type": "SWITCH_STACK_CONDUCTOR_CHANGE" + }, + { + "api_display_name": "Stack Member Added/Removed", + "api_id": 1309, + "category": "SWITCH", + "display_name": "Stack Member Added/Removed", + "name_match": "exact", + "source_type": "SWITCH_STACK_MEMBER_ADDED_REMOVED" + }, + { + "api_display_name": "Stack Link Status Change", + "api_id": 1313, + "category": "SWITCH", + "display_name": "Stack Link Status Change", + "name_match": "exact", + "source_type": "SWITCH_STACK_MEMBER_VSF_LINK_STATUS_CHANGE" + }, + { + "api_display_name": "Switch STP Root Change", + "api_id": 1308, + "category": "SWITCH", + "display_name": "Switch STP Root Change", + "name_match": "exact", + "source_type": "SWITCH_STP_ROOT_CHANGE" + }, + { + "api_display_name": "Switch Uplink Port Usage", + "api_id": 1311, + "category": "SWITCH", + "display_name": "Switch Uplink Port Usage", + "name_match": "exact", + "source_type": "SWITCH_UPLINK_PORT_OVER_UTILIZATION" + }, + { + "api_display_name": "Switch Uplink Port Status Change", + "api_id": 1314, + "category": "SWITCH", + "display_name": "Switch Uplink Port Status Change", + "name_match": "exact", + "source_type": "SWITCH_UPLINK_PORT_STATUS_CHANGE" + }, + { + "api_display_name": "Switch Disconnected", + "api_id": 203, + "category": "SWITCH", + "display_name": "Switch Disconnected", + "name_match": "exact", + "source_type": "Switch Disconnected" + }, + { + "api_display_name": "Switch Mismatch Config", + "api_id": 206, + "category": "SWITCH", + "display_name": "Switch Mismatch Config", + "name_match": "exact", + "source_type": "Switch Mismatch Config" + }, + { + "api_display_name": "Switch NAE Agent Status", + "api_id": 209, + "category": "SWITCH", + "display_name": "Switch NAE Agent Status", + "name_match": "exact", + "source_type": "Switch NAE Granular Status" + }, + { + "api_display_name": "Switch NAE Status", + "api_id": 208, + "category": "SWITCH", + "display_name": "Switch NAE Status", + "name_match": "exact", + "source_type": "Switch NAE Status" + }, + { + "api_display_name": "Switch Routing Neighbor Status Change (AOS-CX)", + "api_id": 1315, + "category": "SWITCH", + "display_name": "Switch Routing Neighbor Status Change (AOS-CX)", + "name_match": "exact", + "source_type": "Switch routing neighbor status change" + }, + { + "api_display_name": "Uplink Changed", + "api_id": 17, + "category": "ACCESS POINT", + "display_name": "Uplink Changed", + "name_match": "exact", + "source_type": "Uplink Changed" + }, + { + "api_display_name": "User account deleted", + "api_id": 15, + "category": "USER", + "display_name": "User Account Deleted", + "name_match": "exact", + "source_type": "User account deleted" + }, + { + "api_display_name": "User account edited", + "api_id": 16, + "category": "USER", + "display_name": "User Account Edited", + "name_match": "exact", + "source_type": "User account edited" + }, + { + "api_display_name": "VGW VM Down", + "api_id": 1702, + "category": "GATEWAY", + "display_name": "VGW VM Down", + "name_match": "exact", + "source_type": "VGW_HEALTH_STATE_CHANGE_DETECTED" + }, + { + "api_display_name": "VM IoT Connector Down Alert", + "api_id": 3004, + "category": "IOT", + "display_name": "VM IoT Connector Down Alert", + "name_match": "exact", + "source_type": "VM_IOT_CONNECTOR_DOWN_ALERT" + }, + { + "api_display_name": "VM IoT Connector Flapping Alert", + "api_id": 3006, + "category": "IOT", + "display_name": "VM IoT Connector Flapping Alert", + "name_match": "exact", + "source_type": "VM_IOT_CONNECTOR_FLAPPING_ALERT" + }, + { + "api_display_name": "VM IoT Connector Long Term Down Alert", + "api_id": 3007, + "category": "IOT", + "display_name": "VM IoT Connector Long Term Down Alert", + "name_match": "exact", + "source_type": "VM_IOT_CONNECTOR_LONG_TERM_DOWN_ALERT" + }, + { + "api_display_name": "Virtual Controller Disconnected", + "api_id": 2, + "category": "ACCESS POINT", + "display_name": "Virtual Controller Disconnected", + "name_match": "exact", + "source_type": "Virtual controller disconnected" + }, + { + "api_display_name": "Uplink speed flapping", + "api_id": 1602, + "category": "GATEWAY", + "display_name": "Uplink Speed Flapping", + "name_match": "exact", + "source_type": "WAN_AUTO_NEGOTIATION_FLAP" + }, + { + "api_display_name": "All IPSec SAs Down", + "api_id": 1552, + "category": "GATEWAY", + "display_name": "All IPSec SAs Down", + "name_match": "exact", + "source_type": "WAN_IPSEC_SA_ALL_DOWN" + }, + { + "api_display_name": "IPSec SA Down", + "api_id": 1551, + "category": "GATEWAY", + "display_name": "IPSec SA Down", + "name_match": "exact", + "source_type": "WAN_IPSEC_SA_DOWN" + }, + { + "api_display_name": "IPSec Establishment Failure", + "api_id": 1550, + "category": "GATEWAY", + "display_name": "IPSec Establishment Failure", + "name_match": "exact", + "source_type": "WAN_IPSEC_SA_ESTABILSHMENT_FAILED" + }, + { + "api_display_name": "Tunnel flapping", + "api_id": 1601, + "category": "GATEWAY", + "display_name": "Tunnel Flapping", + "name_match": "exact", + "source_type": "WAN_TUNNEL_FLAP" + }, + { + "api_display_name": "WAN Uplink Autonegotiation state change", + "api_id": 1506, + "category": "GATEWAY", + "display_name": "WAN Uplink Autonegotiation State Change", + "name_match": "exact", + "source_type": "WAN_UPLINK_AUTONEGOTIATION_STATE_CHANGE" + }, + { + "api_display_name": "Uplink flapping", + "api_id": 1600, + "category": "GATEWAY", + "display_name": "Uplink Flapping", + "name_match": "exact", + "source_type": "WAN_UPLINK_FLAP" + }, + { + "api_display_name": "WAN Uplink Input errors", + "api_id": 1507, + "category": "GATEWAY", + "display_name": "WAN Uplink Input Errors", + "name_match": "exact", + "source_type": "WAN_UPLINK_INPUT_ERRORS" + }, + { + "api_display_name": "VPN Peer Failover", + "api_id": 1504, + "category": "GATEWAY", + "display_name": "VPN Peer Failover", + "name_match": "exact", + "source_type": "WAN_UPLINK_LOAD_BALANCE_PEER_FAILOVER" + }, + { + "api_display_name": "WAN Uplink Output errors", + "api_id": 1508, + "category": "GATEWAY", + "display_name": "WAN Uplink Output Errors", + "name_match": "exact", + "source_type": "WAN_UPLINK_OUTPUT_ERRORS" + }, + { + "api_display_name": "WAN Uplink PHY errors", + "api_id": 1509, + "category": "GATEWAY", + "display_name": "WAN Uplink PHY Errors", + "name_match": "exact", + "source_type": "WAN_UPLINK_PHY_ERRORS" + }, + { + "api_display_name": "WAN Health-check failure", + "api_id": 1501, + "category": "GATEWAY", + "display_name": "WAN Health-Check Failure", + "name_match": "exact", + "source_type": "WAN_UPLINK_REACHABILITY_HEALTH_CHECK_IP_FAILED" + }, + { + "api_display_name": "WAN VPN-peer unreachable", + "api_id": 1502, + "category": "GATEWAY", + "display_name": "WAN VPN-Peer Unreachable", + "name_match": "exact", + "source_type": "WAN_UPLINK_REACHABILITY_VPN_PEER_FAILED" + }, + { + "api_display_name": "WAN Uplink Status change", + "api_id": 1505, + "category": "GATEWAY", + "display_name": "WAN Uplink Status Change", + "name_match": "exact", + "source_type": "WAN_UPLINK_STATUS_CHANGE" + } +] diff --git a/transition/alert-inventory/data/classic-central-ui-alerts.json b/transition/alert-inventory/data/classic-central-ui-alerts.json new file mode 100644 index 0000000..636e6fb --- /dev/null +++ b/transition/alert-inventory/data/classic-central-ui-alerts.json @@ -0,0 +1,127 @@ +[ + {"category": "USER", "display_name": "New User Account Added"}, + {"category": "USER", "display_name": "User Account Deleted"}, + {"category": "USER", "display_name": "User Account Edited"}, + {"category": "ACCESS POINT", "display_name": "New Virtual Controller Detected"}, + {"category": "ACCESS POINT", "display_name": "AP Disconnected"}, + {"category": "ACCESS POINT", "display_name": "Client Attack Detected"}, + {"category": "ACCESS POINT", "display_name": "Modem Unplugged"}, + {"category": "ACCESS POINT", "display_name": "AP CPU Utilization"}, + {"category": "ACCESS POINT", "display_name": "Radio Noise Floor"}, + {"category": "ACCESS POINT", "display_name": "Radio Frames Retry Percent"}, + {"category": "ACCESS POINT", "display_name": "Radio Non Wi-Fi Utilization"}, + {"category": "ACCESS POINT", "display_name": "Airgroup Alerts"}, + {"category": "ACCESS POINT", "display_name": "AP DHCP Pool Consumption Alert"}, + {"category": "ACCESS POINT", "display_name": "Virtual Controller Disconnected"}, + {"category": "ACCESS POINT", "display_name": "Rogue AP Detected"}, + {"category": "ACCESS POINT", "display_name": "Uplink Changed"}, + {"category": "ACCESS POINT", "display_name": "Insufficient Power Supplied"}, + {"category": "ACCESS POINT", "display_name": "AP Memory Utilization"}, + {"category": "ACCESS POINT", "display_name": "Connected Clients Per VC"}, + {"category": "ACCESS POINT", "display_name": "AP Tunnel Down"}, + {"category": "ACCESS POINT", "display_name": "AP Crash"}, + {"category": "ACCESS POINT", "display_name": "AP Routing Table Limit"}, + {"category": "ACCESS POINT", "display_name": "IAP Firmware Upgrade Failed"}, + {"category": "ACCESS POINT", "display_name": "New AP Detected"}, + {"category": "ACCESS POINT", "display_name": "Infrastructure Attack Detected"}, + {"category": "ACCESS POINT", "display_name": "Modem Plugged"}, + {"category": "ACCESS POINT", "display_name": "AP With Missing Radios"}, + {"category": "ACCESS POINT", "display_name": "Radio Channel Utilization"}, + {"category": "ACCESS POINT", "display_name": "Connected Clients Per AP"}, + {"category": "ACCESS POINT", "display_name": "All AP Tunnels Down"}, + {"category": "ACCESS POINT", "display_name": "AP Reboot"}, + {"category": "ACCESS POINT", "display_name": "DPP Attack"}, + {"category": "SWITCH", "display_name": "New Switch Connected"}, + {"category": "SWITCH", "display_name": "Switch Hardware Failure"}, + {"category": "SWITCH", "display_name": "Switch CPU Utilization"}, + {"category": "SWITCH", "display_name": "Switch Port Rx Rate"}, + {"category": "SWITCH", "display_name": "Switch Port Duplex Mode"}, + {"category": "SWITCH", "display_name": "Stack Member Added/Removed"}, + {"category": "SWITCH", "display_name": "Switch Reboot"}, + {"category": "SWITCH", "display_name": "Switch Routing Neighbor Status Change (AOS-CX)"}, + {"category": "SWITCH", "display_name": "Switch Disconnected"}, + {"category": "SWITCH", "display_name": "Switch NAE Status"}, + {"category": "SWITCH", "display_name": "Switch Memory Utilization"}, + {"category": "SWITCH", "display_name": "Switch Port Input Errors"}, + {"category": "SWITCH", "display_name": "Switch PoE Utilization"}, + {"category": "SWITCH", "display_name": "Switch Stack Conductor Change"}, + {"category": "SWITCH", "display_name": "Stack Link Status Change"}, + {"category": "SWITCH", "display_name": "Switch Mismatch Config"}, + {"category": "SWITCH", "display_name": "Switch NAE Agent Status"}, + {"category": "SWITCH", "display_name": "Switch Port Tx Rate"}, + {"category": "SWITCH", "display_name": "Switch Port Output Errors"}, + {"category": "SWITCH", "display_name": "Switch STP Root Change"}, + {"category": "SWITCH", "display_name": "Switch Uplink Port Usage"}, + {"category": "SWITCH", "display_name": "Switch Uplink Port Status Change"}, + {"category": "GATEWAY", "display_name": "SLA DPS Compliance Violations"}, + {"category": "GATEWAY", "display_name": "Gateway CPU Utilization"}, + {"category": "GATEWAY", "display_name": "OSPF Session Error"}, + {"category": "GATEWAY", "display_name": "Routing Table Limit"}, + {"category": "GATEWAY", "display_name": "WAN Health-Check Failure"}, + {"category": "GATEWAY", "display_name": "WAN Uplink Status Change"}, + {"category": "GATEWAY", "display_name": "WAN Uplink Output Errors"}, + {"category": "GATEWAY", "display_name": "Gateway Cellular Data Usage"}, + {"category": "GATEWAY", "display_name": "IPSec SA Down"}, + {"category": "GATEWAY", "display_name": "Uplink Flapping"}, + {"category": "GATEWAY", "display_name": "EST Enrollment Failure"}, + {"category": "GATEWAY", "display_name": "Gateway Joining Cluster"}, + {"category": "GATEWAY", "display_name": "Gateway Cluster Client Capacity"}, + {"category": "GATEWAY", "display_name": "Gateway IDS/IPS Engine CPU Utilization"}, + {"category": "GATEWAY", "display_name": "Gateway Threat Count"}, + {"category": "GATEWAY", "display_name": "New Gateway Connected"}, + {"category": "GATEWAY", "display_name": "Gateway Memory Utilization"}, + {"category": "GATEWAY", "display_name": "BGP Session"}, + {"category": "GATEWAY", "display_name": "BGP Neighbor Route Limit"}, + {"category": "GATEWAY", "display_name": "WAN VPN-Peer Unreachable"}, + {"category": "GATEWAY", "display_name": "WAN Uplink Autonegotiation State Change"}, + {"category": "GATEWAY", "display_name": "WAN Uplink PHY Errors"}, + {"category": "GATEWAY", "display_name": "Gateway Device Flash/Memory Usage", "api_match": {"source_type": "FLASH_MEMORY_USAGE", "api_display_name": "Gateway Device Flash Memory Usage", "reason": "approved_api_ui_name_difference"}}, + {"category": "GATEWAY", "display_name": "All IPSec SAs Down"}, + {"category": "GATEWAY", "display_name": "Tunnel Flapping"}, + {"category": "GATEWAY", "display_name": "VGW VM Down"}, + {"category": "GATEWAY", "display_name": "Gateway Leaving Cluster"}, + {"category": "GATEWAY", "display_name": "Gateway Firmware Upgrade Failed"}, + {"category": "GATEWAY", "display_name": "Gateway IDS/IPS Engine Memory Utilization"}, + {"category": "GATEWAY", "display_name": "Gateway Threat Count Per Signature"}, + {"category": "GATEWAY", "display_name": "Gateway Disconnected"}, + {"category": "GATEWAY", "display_name": "Gateway Emergency Mode"}, + {"category": "GATEWAY", "display_name": "Gateway Base License Capacity Limit Exceeded"}, + {"category": "GATEWAY", "display_name": "Overlay Route Orchestrator Connection"}, + {"category": "GATEWAY", "display_name": "VPN Peer Failover"}, + {"category": "GATEWAY", "display_name": "WAN Uplink Input Errors"}, + {"category": "GATEWAY", "display_name": "DHCP Pool Consumption Alert"}, + {"category": "GATEWAY", "display_name": "IPSec Establishment Failure"}, + {"category": "GATEWAY", "display_name": "CFG-SET Advertisement Failure"}, + {"category": "GATEWAY", "display_name": "Uplink Speed Flapping"}, + {"category": "GATEWAY", "display_name": "Gateway Cluster VLAN Mismatch"}, + {"category": "GATEWAY", "display_name": "Gateway Cluster Leader Change"}, + {"category": "GATEWAY", "display_name": "Gateway IDS/IPS Engine Error State"}, + {"category": "GATEWAY", "display_name": "Gateway IDS/IPS Engine Packet Dropped Detected"}, + {"category": "GATEWAY", "display_name": "Gateway Threat Count Per User"}, + {"category": "CONNECTIVITY", "display_name": "DNS Delay Detected"}, + {"category": "CONNECTIVITY", "display_name": "DHCP Failure Detected"}, + {"category": "CONNECTIVITY", "display_name": "Association Delay Detected"}, + {"category": "CONNECTIVITY", "display_name": "Wi-Fi Security Key-Exchange Failure Detected"}, + {"category": "CONNECTIVITY", "display_name": "MAC Authentication Delay Detected"}, + {"category": "CONNECTIVITY", "display_name": "Captive Portal Failure Detected"}, + {"category": "CONNECTIVITY", "display_name": "DNS Failure Detected"}, + {"category": "CONNECTIVITY", "display_name": "Authentication Delay Detected"}, + {"category": "CONNECTIVITY", "display_name": "Association Failure Detected"}, + {"category": "CONNECTIVITY", "display_name": "802.1x Authentication Delay Detected"}, + {"category": "CONNECTIVITY", "display_name": "MAC Authentication Failure Detected"}, + {"category": "CONNECTIVITY", "display_name": "DHCP Delay Detected"}, + {"category": "CONNECTIVITY", "display_name": "Authentication Failure Detected"}, + {"category": "CONNECTIVITY", "display_name": "Wi-Fi Security Key-Exchange Delay Detected"}, + {"category": "CONNECTIVITY", "display_name": "802.1x Authentication Failure Detected"}, + {"category": "CONNECTIVITY", "display_name": "Captive Portal Delay Detected"}, + {"category": "AUDIT", "display_name": "Config Change Detected"}, + {"category": "SITE", "display_name": "Aggregated Device Disconnections"}, + {"category": "IP MANAGEMENT SYSTEM", "display_name": "IPMS Pool Capacity Alert"}, + {"category": "IOT", "display_name": "New App Installed Alert"}, + {"category": "IOT", "display_name": "Existing Transport Profile Uninstalled Alert"}, + {"category": "IOT", "display_name": "VM IoT Connector Long Term Down Alert"}, + {"category": "IOT", "display_name": "Existing App Uninstalled Alert"}, + {"category": "IOT", "display_name": "VM IoT Connector Down Alert"}, + {"category": "IOT", "display_name": "New Transport Profile Installed Alert"}, + {"category": "IOT", "display_name": "VM IoT Connector Flapping Alert"} +] diff --git a/transition/alert-inventory/docs/enabled-alerts-csv.png b/transition/alert-inventory/docs/enabled-alerts-csv.png new file mode 100644 index 0000000..624bf97 Binary files /dev/null and b/transition/alert-inventory/docs/enabled-alerts-csv.png differ diff --git a/transition/alert-inventory/docs/enabled-alerts-results.png b/transition/alert-inventory/docs/enabled-alerts-results.png new file mode 100644 index 0000000..0bbc815 Binary files /dev/null and b/transition/alert-inventory/docs/enabled-alerts-results.png differ diff --git a/transition/alert-inventory/docs/enabled-alerts-workflow.gif b/transition/alert-inventory/docs/enabled-alerts-workflow.gif new file mode 100644 index 0000000..0173e24 Binary files /dev/null and b/transition/alert-inventory/docs/enabled-alerts-workflow.gif differ diff --git a/transition/alert-inventory/requirements.txt b/transition/alert-inventory/requirements.txt new file mode 100644 index 0000000..0d89964 --- /dev/null +++ b/transition/alert-inventory/requirements.txt @@ -0,0 +1,3 @@ +fastapi==0.116.1 +uvicorn==0.35.0 +pycentral==2.0a23 diff --git a/transition/alert-inventory/static/assets/index-DLuFTCrs.js b/transition/alert-inventory/static/assets/index-DLuFTCrs.js new file mode 100644 index 0000000..d633f55 --- /dev/null +++ b/transition/alert-inventory/static/assets/index-DLuFTCrs.js @@ -0,0 +1,50 @@ +var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;li[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(n,r,o)=>(o=n==null?{}:e(i(n)),s(r||!n||!n.__esModule||!a.call(n,`default`)?t(o,`default`,{value:n,enumerable:!0}):o,n));(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var l=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.iterator;function m(e){return typeof e!=`object`||!e?null:(e=p&&e[p]||e[`@@iterator`],typeof e==`function`?e:null)}var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g=Object.assign,_={};function v(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}v.prototype.isReactComponent={},v.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=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,e,t,`setState`)},v.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function y(){}y.prototype=v.prototype;function b(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}var x=b.prototype=new y;x.constructor=b,g(x,v.prototype),x.isPureReactComponent=!0;var S=Array.isArray;function C(){}var w={H:null,A:null,T:null,S:null},T=Object.prototype.hasOwnProperty;function E(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function D(e,t){return E(e.type,t,e.props)}function O(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function k(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var ee=/\/+/g;function A(e,t){return typeof e==`object`&&e&&e.key!=null?k(``+e.key):t.toString(36)}function j(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(C,C):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function M(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,M(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+A(e,0):a,S(o)?(i=``,c!=null&&(i=c.replace(ee,`$&/`)+`/`),M(o,r,i,``,function(e){return e})):o!=null&&(O(o)&&(o=D(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(ee,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(S(e))for(var u=0;u{t.exports=l()})),d=o((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m){if(n(c)!==null)m=!0,S||(S=!0,O());else{var t=n(l);t!==null&&A(x,t.startTime-e)}}}var S=!1,C=-1,w=5,T=-1;function E(){return g?!0:!(e.unstable_now()-Tt&&E());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&A(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}}}finally{i?O():S=!1}}}var O;if(typeof y==`function`)O=function(){y(D)};else if(typeof MessageChannel<`u`){var k=new MessageChannel,ee=k.port2;k.port1.onmessage=D,O=function(){ee.postMessage(null)}}else O=function(){_(D,0)};function A(t,n){C=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(C),C=-1):h=!0,A(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,S||(S=!0,O()))),r},e.unstable_shouldYield=E,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),f=o(((e,t)=>{t.exports=d()})),p=o((e=>{var t=u();function n(e){var t=`https://react.dev/errors/`+e;if(1{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=p()})),h=o((e=>{var t=f(),n=u(),r=m();function i(e){var t=`https://react.dev/errors/`+e;if(1re||(e.current=ne[re],ne[re]=null,re--)}function R(e,t){re++,ne[re]=e.current,e.current=t}var ae=ie(null),oe=ie(null),se=ie(null),ce=ie(null);function le(e,t){switch(R(se,t),R(oe,e),R(ae,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Vd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Vd(t),e=Hd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}L(ae),R(ae,e)}function ue(){L(ae),L(oe),L(se)}function de(e){e.memoizedState!==null&&R(ce,e);var t=ae.current,n=Hd(t,e.type);t!==n&&(R(oe,e),R(ae,n))}function fe(e){oe.current===e&&(L(ae),L(oe)),ce.current===e&&(L(ce),Qf._currentValue=te)}var pe,me;function he(e){if(pe===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);pe=t&&t[1]||``,me=-1)`:-1i||c[r]!==l[i]){var u=` +`+c[r].replace(` at new `,` at `);return e.displayName&&u.includes(``)&&(u=u.replace(``,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{ge=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?he(n):``}function ve(e,t){switch(e.tag){case 26:case 27:case 5:return he(e.type);case 16:return he(`Lazy`);case 13:return e.child!==t&&t!==null?he(`Suspense Fallback`):he(`Suspense`);case 19:return he(`SuspenseList`);case 0:case 15:return _e(e.type,!1);case 11:return _e(e.type.render,!1);case 1:return _e(e.type,!0);case 31:return he(`Activity`);default:return``}}function ye(e){try{var t=``,n=null;do t+=ve(e,n),n=e,e=e.return;while(e);return t}catch(e){return` +Error generating stack: `+e.message+` +`+e.stack}}var be=Object.prototype.hasOwnProperty,xe=t.unstable_scheduleCallback,Se=t.unstable_cancelCallback,Ce=t.unstable_shouldYield,we=t.unstable_requestPaint,Te=t.unstable_now,Ee=t.unstable_getCurrentPriorityLevel,De=t.unstable_ImmediatePriority,Oe=t.unstable_UserBlockingPriority,ke=t.unstable_NormalPriority,Ae=t.unstable_LowPriority,je=t.unstable_IdlePriority,Me=t.log,Ne=t.unstable_setDisableYieldValue,Pe=null,Fe=null;function Ie(e){if(typeof Me==`function`&&Ne(e),Fe&&typeof Fe.setStrictMode==`function`)try{Fe.setStrictMode(Pe,e)}catch{}}var Le=Math.clz32?Math.clz32:Be,Re=Math.log,ze=Math.LN2;function Be(e){return e>>>=0,e===0?32:31-(Re(e)/ze|0)|0}var Ve=256,He=262144,Ue=4194304;function z(e){var t=e&42;if(t!==0)return t;switch(e&-e){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 e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function We(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=z(n))):i=z(o):i=z(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=z(n))):i=z(o)):i=z(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function Ge(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function Ke(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+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 t+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 qe(){var e=Ue;return Ue<<=1,!(Ue&62914560)&&(Ue=4194304),e}function Je(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function Ye(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function Xe(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0`u`||window.document===void 0||window.document.createElement===void 0),rn=!1;if(nn)try{var an={};Object.defineProperty(an,"passive",{get:function(){rn=!0}}),window.addEventListener(`test`,an,an),window.removeEventListener(`test`,an,an)}catch{rn=!1}var on=null,sn=null,cn=null;function ln(){if(cn)return cn;var e,t=sn,n=t.length,r,i=`value`in on?on.value:on.textContent,a=i.length;for(e=0;e=Bn),Un=` `,Wn=!1;function Gn(e,t){switch(e){case`keyup`:return Rn.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function Kn(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var qn=!1;function Jn(e,t){switch(e){case`compositionend`:return Kn(t);case`keypress`:return t.which===32?(Wn=!0,Un):null;case`textInput`:return e=t.data,e===Un&&Wn?null:e;default:return null}}function Yn(e,t){if(qn)return e===`compositionend`||!zn&&Gn(e,t)?(e=ln(),cn=sn=on=null,qn=!1,e):null;switch(e){case`paste`:return null;case`keypress`:if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=_r(n)}}function yr(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?yr(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function br(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=Mt(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=Mt(e.document)}return t}function xr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t===`input`&&(e.type===`text`||e.type===`search`||e.type===`tel`||e.type===`url`||e.type===`password`)||t===`textarea`||e.contentEditable===`true`)}var Sr=nn&&`documentMode`in document&&11>=document.documentMode,Cr=null,wr=null,Tr=null,Er=!1;function Dr(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Er||Cr==null||Cr!==Mt(r)||(r=Cr,`selectionStart`in r&&xr(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Tr&&gr(Tr,r)||(Tr=r,r=Td(wr,`onSelect`),0>=o,i-=o,yi=1<<32-Le(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),K&&xi(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(a,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(a,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(a,h),K&&xi(a,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(a,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return K&&xi(a,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,a,g,v.value,l),v!==null&&(e&&v.alternate!==null&&h.delete(v.key===null?g:v.key),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(a,e)}),K&&xi(a,g),u}function b(e,r,o,c){if(typeof o==`object`&&o&&o.type===y&&o.key===null&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case _:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===y){if(r.tag===7){n(e,r.sibling),c=a(r,o.props.children),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===O&&xa(l)===r.type){n(e,r.sibling),c=a(r,o.props),Oa(c,o),c.return=e,e=c;break a}n(e,r);break}t(e,r),r=r.sibling}o.type===y?(c=oi(o.props.children,e.mode,c,o.key),c.return=e,e=c):(c=ai(o.type,o.key,o.props,null,e.mode,c),Oa(c,o),c.return=e,e=c)}return s(e);case v:a:{for(l=o.key;r!==null;){if(r.key===l){if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=a(r,o.children||[]),c.return=e,e=c;break a}n(e,r);break}t(e,r),r=r.sibling}c=li(o,e.mode,c),c.return=e,e=c}return s(e);case O:return o=xa(o),b(e,r,o,c)}if(P(o))return h(e,r,o,c);if(j(o)){if(l=j(o),typeof l!=`function`)throw Error(i(150));return o=l.call(o),g(e,r,o,c)}if(typeof o.then==`function`)return b(e,r,Da(o),c);if(o.$$typeof===C)return b(e,r,Yi(e,o),c);ka(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=a(r,o),c.return=e,e=c):(n(e,r),c=si(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{Ea=0;var i=b(e,t,n,r);return Ta=null,i}catch(t){if(t===ha||t===_a)throw t;var a=ti(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var ja=Aa(!0),Ma=Aa(!1),Na=!1;function Pa(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Fa(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function Ia(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function La(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,Y&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=Qr(e),Zr(e,null,n),t}return Jr(e,r,t,n),Qr(e)}function Ra(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Qe(e,n)}}function za(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var Ba=!1;function Va(){if(Ba){var e=oa;if(e!==null)throw e}}function Ha(e,t,n,r){Ba=!1;var i=e.updateQueue;Na=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane&-536870913,p=f!==s.lane;if(p?(Z&f)===f:(r&f)===f){f!==0&&f===aa&&(Ba=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var m=e,g=s;f=t;var _=n;switch(g.tag){case 1:if(m=g.payload,typeof m==`function`){d=m.call(_,d,f);break a}d=m;break a;case 3:m.flags=m.flags&-65537|128;case 0:if(m=g.payload,f=typeof m==`function`?m.call(_,d,f):m,f==null)break a;d=h({},d,f);break a;case 2:Na=!0}}f=s.callback,f!==null&&(e.flags|=64,p&&(e.flags|=8192),p=i.callbacks,p===null?i.callbacks=[f]:p.push(f))}else p={lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=p,c=d):u=u.next=p,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;p=s,s=p.next,p.next=null,i.lastBaseUpdate=p,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),Wl|=o,e.lanes=o,e.memoizedState=d}}function Ua(e,t){if(typeof e!=`function`)throw Error(i(191,e));e.call(t)}function Wa(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=F.T,s={};F.T=s,ks(e,!1,t,n);try{var c=i(),l=F.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?Os(e,t,la(c,r),du(e)):Os(e,t,r,du(e))}catch(n){Os(e,t,{then:function(){},status:`rejected`,reason:n},du())}finally{I.p=a,o!==null&&s.types!==null&&(o.types=s.types),F.T=o}}function vs(){}function ys(e,t,n,r){if(e.tag!==5)throw Error(i(476));var a=bs(e).queue;_s(e,a,t,te,n===null?vs:function(){return xs(e),n(r)})}function bs(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:te,baseState:te,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Ao,lastRenderedState:te},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Ao,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function xs(e){var t=bs(e);t.next===null&&(t=e.alternate.memoizedState),Os(e,t.next.queue,{},du())}function Ss(){return Ji(Qf)}function Cs(){return To().memoizedState}function ws(){return To().memoizedState}function Ts(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=du();e=Ia(n);var r=La(t,e,n);r!==null&&(pu(r,t,n),Ra(r,t,n)),t={cache:ta()},e.payload=t;return}t=t.return}}function Es(e,t,n){var r=du();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},As(e)?js(t,n):(n=Yr(e,t,n,r),n!==null&&(pu(n,e,r),Ms(n,t,r)))}function Ds(e,t,n){Os(e,t,n,du())}function Os(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(As(e))js(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,hr(s,o))return Jr(e,t,i,0),Il===null&&qr(),!1}catch{}if(n=Yr(e,t,i,r),n!==null)return pu(n,e,r),Ms(n,t,r),!0}return!1}function ks(e,t,n,r){if(r={lane:2,revertLane:ud(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},As(e)){if(t)throw Error(i(479))}else t=Yr(e,n,r,2),t!==null&&pu(t,e,2)}function As(e){var t=e.alternate;return e===q||t!==null&&t===q}function js(e,t){co=so=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Ms(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Qe(e,n)}}var Ns={readContext:Ji,use:Oo,useCallback:ho,useContext:ho,useEffect:ho,useImperativeHandle:ho,useLayoutEffect:ho,useInsertionEffect:ho,useMemo:ho,useReducer:ho,useRef:ho,useState:ho,useDebugValue:ho,useDeferredValue:ho,useTransition:ho,useSyncExternalStore:ho,useId:ho,useHostTransitionStatus:ho,useFormState:ho,useActionState:ho,useOptimistic:ho,useMemoCache:ho,useCacheRefresh:ho};Ns.useEffectEvent=ho;var Ps={readContext:Ji,use:Oo,useCallback:function(e,t){return wo().memoizedState=[e,t===void 0?null:t],e},useContext:Ji,useEffect:is,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),ns(4194308,4,us.bind(null,t,e),n)},useLayoutEffect:function(e,t){return ns(4194308,4,e,t)},useInsertionEffect:function(e,t){ns(4,2,e,t)},useMemo:function(e,t){var n=wo();t=t===void 0?null:t;var r=e();if(lo){Ie(!0);try{e()}finally{Ie(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=wo();if(n!==void 0){var i=n(t);if(lo){Ie(!0);try{n(t)}finally{Ie(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=Es.bind(null,q,e),[r.memoizedState,e]},useRef:function(e){var t=wo();return e={current:e},t.memoizedState=e},useState:function(e){e=Bo(e);var t=e.queue,n=Ds.bind(null,q,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:fs,useDeferredValue:function(e,t){return hs(wo(),e,t)},useTransition:function(){var e=Bo(!1);return e=_s.bind(null,q,e.queue,!0,!1),wo().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=q,a=wo();if(K){if(n===void 0)throw Error(i(407));n=n()}else{if(n=t(),Il===null)throw Error(i(349));Z&127||Fo(r,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,is(Lo.bind(null,r,o,e),[e]),r.flags|=2048,es(9,{destroy:void 0},Io.bind(null,r,o,n,t),null),n},useId:function(){var e=wo(),t=Il.identifierPrefix;if(K){var n=bi,r=yi;n=(r&~(1<<32-Le(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=uo++,0<\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(a,{is:r.is}):s.createElement(a)}}o[it]=t,o[at]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch(Pd(o,a,r),a){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&Oc(t)}}return Nc(t),kc(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&Oc(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(i(166));if(e=se.current,Pi(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,a=Ei,a!==null)switch(a.tag){case 27:case 5:r=a.memoizedProps}e[it]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||jd(e.nodeValue,n)),e||ji(t,!0)}else e=Bd(e).createTextNode(r),e[it]=t,t.stateNode=e}return Nc(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=Pi(t),n!==null){if(e===null){if(!r)throw Error(i(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(i(557));e[it]=t}else Fi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Nc(t),e=!1}else n=Ii(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(no(t),t):(no(t),null);if(t.flags&128)throw Error(i(558))}return Nc(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(a=Pi(t),r!==null&&r.dehydrated!==null){if(e===null){if(!a)throw Error(i(318));if(a=t.memoizedState,a=a===null?null:a.dehydrated,!a)throw Error(i(317));a[it]=t}else Fi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Nc(t),a=!1}else a=Ii(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(no(t),t):(no(t),null)}return no(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,a=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(a=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==a&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),jc(t,t.updateQueue),Nc(t),null);case 4:return ue(),e===null&&xd(t.stateNode.containerInfo),Nc(t),null;case 10:return Hi(t.type),Nc(t),null;case 19:if(L(ro),r=t.memoizedState,r===null)return Nc(t),null;if(a=!!(t.flags&128),o=r.rendering,o===null){if(a)Mc(r,!1);else{if(Ul!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=io(e),o!==null){for(t.flags|=128,Mc(r,!1),e=o.updateQueue,t.updateQueue=e,jc(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)ii(n,e),n=n.sibling;return R(ro,ro.current&1|2),K&&xi(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&Te()>eu&&(t.flags|=128,a=!0,Mc(r,!1),t.lanes=4194304)}}else{if(!a){if(e=io(o),e!==null){if(t.flags|=128,a=!0,e=e.updateQueue,t.updateQueue=e,jc(t,e),Mc(r,!0),r.tail===null&&r.tailMode===`hidden`&&!o.alternate&&!K)return Nc(t),null}else 2*Te()-r.renderingStartTime>eu&&n!==536870912&&(t.flags|=128,a=!0,Mc(r,!1),t.lanes=4194304)}r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}return r.tail===null?(Nc(t),null):(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=Te(),e.sibling=null,n=ro.current,R(ro,a?n&1|2:n&1),K&&xi(t,r.treeForkCount),e);case 22:case 23:return no(t),Ya(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(Nc(t),t.subtreeFlags&6&&(t.flags|=8192)):Nc(t),n=t.updateQueue,n!==null&&jc(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&L(da),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),Hi(ea),Nc(t),null;case 25:return null;case 30:return null}throw Error(i(156,t.tag))}function Fc(e,t){switch(wi(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Hi(ea),ue(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return fe(t),null;case 31:if(t.memoizedState!==null){if(no(t),t.alternate===null)throw Error(i(340));Fi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(no(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));Fi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return L(ro),null;case 4:return ue(),null;case 10:return Hi(t.type),null;case 22:case 23:return no(t),Ya(),e!==null&&L(da),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return Hi(ea),null;case 25:return null;default:return null}}function Ic(e,t){switch(wi(t),t.tag){case 3:Hi(ea),ue();break;case 26:case 27:case 5:fe(t);break;case 4:ue();break;case 31:t.memoizedState!==null&&no(t);break;case 13:no(t);break;case 19:L(ro);break;case 10:Hi(t.type);break;case 22:case 23:no(t),Ya(),e!==null&&L(da);break;case 24:Hi(ea)}}function Lc(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Uu(t,t.return,e)}}function Rc(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Uu(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Uu(t,t.return,e)}}function zc(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{Wa(t,n)}catch(t){Uu(e,e.return,t)}}}function Bc(e,t,n){n.props=Vs(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Uu(e,t,n)}}function Vc(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Uu(e,t,n)}}function Hc(e,t){var n=e.ref,r=e.refCleanup;if(n!==null){if(typeof r==`function`)try{r()}catch(n){Uu(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Uu(e,t,n)}else n.current=null}}function Uc(e){var t=e.type,n=e.memoizedProps,r=e.stateNode;try{a:switch(t){case`button`:case`input`:case`select`:case`textarea`:n.autoFocus&&r.focus();break a;case`img`:n.src?r.src=n.src:n.srcSet&&(r.srcset=n.srcSet)}}catch(t){Uu(e,e.return,t)}}function Wc(e,t,n){try{var r=e.stateNode;Fd(r,e.type,n,t),r[at]=t}catch(t){Uu(e,e.return,t)}}function Gc(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&Zd(e.type)||e.tag===4}function Kc(e){a:for(;;){for(;e.sibling===null;){if(e.return===null||Gc(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&Zd(e.type)||e.flags&2||e.child===null||e.tag===4)continue a;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function qc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?(n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n).insertBefore(e,t):(t=n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n,t.appendChild(e),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=Yt));else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode,t=null),e=e.child,e!==null))for(qc(e,t,n),e=e.sibling;e!==null;)qc(e,t,n),e=e.sibling}function Jc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode),e=e.child,e!==null))for(Jc(e,t,n),e=e.sibling;e!==null;)Jc(e,t,n),e=e.sibling}function Yc(e){var t=e.stateNode,n=e.memoizedProps;try{for(var r=e.type,i=t.attributes;i.length;)t.removeAttributeNode(i[0]);Pd(t,r,n),t[it]=e,t[at]=n}catch(t){Uu(e,e.return,t)}}var Xc=!1,Zc=!1,Qc=!1,$c=typeof WeakSet==`function`?WeakSet:Set,el=null;function tl(e,t){if(e=e.containerInfo,Rd=sp,e=br(e),xr(e)){if(`selectionStart`in e)var n={start:e.selectionStart,end:e.selectionEnd};else a:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var a=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break a}var s=0,c=-1,l=-1,u=0,d=0,f=e,p=null;b:for(;;){for(var m;f!==n||a!==0&&f.nodeType!==3||(c=s+a),f!==o||r!==0&&f.nodeType!==3||(l=s+r),f.nodeType===3&&(s+=f.nodeValue.length),(m=f.firstChild)!==null;)p=f,f=m;for(;;){if(f===e)break b;if(p===n&&++u===a&&(c=s),p===o&&++d===r&&(l=s),(m=f.nextSibling)!==null)break;f=p,p=f.parentNode}f=m}n=c===-1||l===-1?null:{start:c,end:l}}else n=null}n||={start:0,end:0}}else n=null;for(zd={focusedElem:e,selectionRange:n},sp=!1,el=t;el!==null;)if(t=el,e=t.child,t.subtreeFlags&1028&&e!==null)e.return=t,el=e;else for(;el!==null;){switch(t=el,o=t.alternate,e=t.flags,t.tag){case 0:if(e&4&&(e=t.updateQueue,e=e===null?null:e.events,e!==null))for(n=0;n title`))),Pd(o,r,n),o[it]=e,gt(o),r=o;break a;case`link`:var s=Vf(`link`,`href`,a).get(r+(n.href||``));if(s){for(var c=0;cg&&(o=g,g=h,h=o);var _=vr(s,h),v=vr(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,F.T=null,n=cu,cu=null;var o=iu,s=ou;if(ru=0,au=iu=null,ou=0,Y&6)throw Error(i(331));var c=Y;if(Y|=4,jl(o.current),Cl(o,o.current,s,n),Y=c,rd(0,!1),Fe&&typeof Fe.onPostCommitFiberRoot==`function`)try{Fe.onPostCommitFiberRoot(Pe,o)}catch{}return!0}finally{I.p=a,F.T=r,zu(e,t)}}function Hu(e,t,n){t=di(n,t),t=qs(e.stateNode,t,2),e=La(e,t,2),e!==null&&(Ye(e,2),nd(e))}function Uu(e,t,n){if(e.tag===3)Hu(e,e,n);else for(;t!==null;){if(t.tag===3){Hu(t,e,n);break}if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(nu===null||!nu.has(r))){e=di(n,e),n=Js(2),r=La(t,n,2),r!==null&&(Ys(n,r,t,e),Ye(r,2),nd(r));break}}t=t.return}}function Wu(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new Fl;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(Vl=!0,i.add(n),e=Gu.bind(null,e,t,n),t.then(e,e))}function Gu(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,Il===e&&(Z&n)===n&&(Ul===4||Ul===3&&(Z&62914560)===Z&&300>Te()-Ql?!(Y&2)&&bu(e,0):Kl|=n,Jl===Z&&(Jl=0)),nd(e)}function Ku(e,t){t===0&&(t=qe()),e=Xr(e,t),e!==null&&(Ye(e,t),nd(e))}function qu(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),Ku(e,n)}function Ju(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(i(314))}r!==null&&r.delete(t),Ku(e,n)}function Yu(e,t){return xe(e,t)}var Xu=null,Zu=null,Qu=!1,$u=!1,ed=!1,td=0;function nd(e){e!==Zu&&e.next===null&&(Zu===null?Xu=Zu=e:Zu=Zu.next=e),$u=!0,Qu||(Qu=!0,ld())}function rd(e,t){if(!ed&&$u){ed=!0;do for(var n=!1,r=Xu;r!==null;){if(!t){if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-Le(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,cd(r,a))}else a=Z,a=We(r,r===Il?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||Ge(r,a)||(n=!0,cd(r,a))}r=r.next}while(n);ed=!1}}function id(){ad()}function ad(){$u=Qu=!1;var e=0;td!==0&&Gd()&&(e=td);for(var t=Te(),n=null,r=Xu;r!==null;){var i=r.next,a=od(r,t);a===0?(r.next=null,n===null?Xu=i:n.next=i,i===null&&(Zu=n)):(n=r,(e!==0||a&3)&&($u=!0)),r=i}ru!==0&&ru!==5||rd(e,!1),td!==0&&(td=0)}function od(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&Id(d)&&(c=c.responseEnd,o+=u*(c`u`?null:document;function xf(e,t,n){var r=bf;if(r&&typeof t==`string`&&t){var i=Pt(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),hf.has(i)||(hf.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),Pd(t,`link`,e),gt(t),r.head.appendChild(t)))}}function Sf(e){_f.D(e),xf(`dns-prefetch`,e,null)}function Cf(e,t){_f.C(e,t),xf(`preconnect`,e,t)}function wf(e,t,n){_f.L(e,t,n);var r=bf;if(r&&e&&t){var i=`link[rel="preload"][as="`+Pt(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+Pt(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+Pt(n.imageSizes)+`"]`)):i+=`[href="`+Pt(e)+`"]`;var a=i;switch(t){case`style`:a=Af(e);break;case`script`:a=Pf(e)}mf.has(a)||(e=h({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),mf.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(jf(a))||t===`script`&&r.querySelector(Ff(a))||(t=r.createElement(`link`),Pd(t,`link`,e),gt(t),r.head.appendChild(t)))}}function Tf(e,t){_f.m(e,t);var n=bf;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+Pt(r)+`"][href="`+Pt(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Pf(e)}if(!mf.has(a)&&(e=h({rel:`modulepreload`,href:e},t),mf.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(Ff(a)))return}r=n.createElement(`link`),Pd(r,`link`,e),gt(r),n.head.appendChild(r)}}}function Ef(e,t,n){_f.S(e,t,n);var r=bf;if(r&&e){var i=ht(r).hoistableStyles,a=Af(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(jf(a)))s.loading=5;else{e=h({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=mf.get(a))&&Rf(e,n);var c=o=r.createElement(`link`);gt(c),Pd(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Lf(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function Df(e,t){_f.X(e,t);var n=bf;if(n&&e){var r=ht(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=h({src:e,async:!0},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),gt(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Of(e,t){_f.M(e,t);var n=bf;if(n&&e){var r=ht(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=h({src:e,async:!0,type:`module`},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),gt(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function kf(e,t,n,r){var a=(a=se.current)?gf(a):null;if(!a)throw Error(i(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(t=Af(n.href),n=ht(a).hoistableStyles,r=n.get(t),r||(r={type:`style`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Af(n.href);var o=ht(a).hoistableStyles,s=o.get(e);if(s||(a=a.ownerDocument||a,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=a.querySelector(jf(e)))&&!o._p&&(s.instance=o,s.state.loading=5),mf.has(e)||(n={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},mf.set(e,n),o||Nf(a,e,n,s.state))),t&&r===null)throw Error(i(528,``));return s}if(t&&r!==null)throw Error(i(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(t=Pf(n),n=ht(a).hoistableScripts,r=n.get(t),r||(r={type:`script`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(i(444,e))}}function Af(e){return`href="`+Pt(e)+`"`}function jf(e){return`link[rel="stylesheet"][`+e+`]`}function Mf(e){return h({},e,{"data-precedence":e.precedence,precedence:null})}function Nf(e,t,n,r){e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)?r.loading=1:(t=e.createElement(`link`),r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2}),Pd(t,`link`,n),gt(t),e.head.appendChild(t))}function Pf(e){return`[src="`+Pt(e)+`"]`}function Ff(e){return`script[async]`+e}function If(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+Pt(n.href)+`"]`);if(r)return t.instance=r,gt(r),r;var a=h({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),gt(r),Pd(r,`style`,a),Lf(r,n.precedence,e),t.instance=r;case`stylesheet`:a=Af(n.href);var o=e.querySelector(jf(a));if(o)return t.state.loading|=4,t.instance=o,gt(o),o;r=Mf(n),(a=mf.get(a))&&Rf(r,a),o=(e.ownerDocument||e).createElement(`link`),gt(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),Pd(o,`link`,r),t.state.loading|=4,Lf(o,n.precedence,e),t.instance=o;case`script`:return o=Pf(n.src),(a=e.querySelector(Ff(o)))?(t.instance=a,gt(a),a):(r=n,(a=mf.get(o))&&(r=h({},n),zf(r,a)),e=e.ownerDocument||e,a=e.createElement(`script`),gt(a),Pd(a,`link`,r),e.head.appendChild(a),t.instance=a);case`void`:return null;default:throw Error(i(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Lf(r,n.precedence,e));return t.instance}function Lf(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function Uf(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Wf(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Gf(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Af(r.href),a=t.querySelector(jf(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=Jf.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,gt(a);return}a=t.ownerDocument||t,r=Mf(r),(i=mf.get(i))&&Rf(r,i),a=a.createElement(`link`),gt(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Pd(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=Jf.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var Kf=0;function qf(e,t){return e.stylesheets&&e.count===0&&Xf(e,e.stylesheets),0Kf?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function Jf(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Xf(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Yf=null;function Xf(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Yf=new Map,t.forEach(Zf,e),Yf=null,Jf.call(e))}function Zf(e,t){if(!(t.state.loading&4)){var n=Yf.get(e);if(n)var r=n.get(null);else{n=new Map,Yf.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=h()})),_=c(u(),1),v=g(),y=(...e)=>e.filter((e,t,n)=>!!e&&e.trim()!==``&&n.indexOf(e)===t).join(` `).trim(),b=e=>e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).toLowerCase(),x=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(e,t,n)=>n?n.toUpperCase():t.toLowerCase()),S=e=>{let t=x(e);return t.charAt(0).toUpperCase()+t.slice(1)},C={xmlns:`http://www.w3.org/2000/svg`,width:24,height:24,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`},w=e=>{for(let t in e)if(t.startsWith(`aria-`)||t===`role`||t===`title`)return!0;return!1},T=(0,_.createContext)({}),E=()=>(0,_.useContext)(T),D=(0,_.forwardRef)(({color:e,size:t,strokeWidth:n,absoluteStrokeWidth:r,className:i=``,children:a,iconNode:o,...s},c)=>{let{size:l=24,strokeWidth:u=2,absoluteStrokeWidth:d=!1,color:f=`currentColor`,className:p=``}=E()??{},m=r??d?Number(n??u)*24/Number(t??l):n??u;return(0,_.createElement)(`svg`,{ref:c,...C,width:t??l??C.width,height:t??l??C.height,stroke:e??f,strokeWidth:m,className:y(`lucide`,p,i),...!a&&!w(s)&&{"aria-hidden":`true`},...s},[...o.map(([e,t])=>(0,_.createElement)(e,t)),...Array.isArray(a)?a:[a]])}),O=(e,t)=>{let n=(0,_.forwardRef)(({className:n,...r},i)=>(0,_.createElement)(D,{ref:i,iconNode:t,className:y(`lucide-${b(S(e))}`,`lucide-${e}`,n),...r}));return n.displayName=S(e),n},k=O(`check`,[[`path`,{d:`M20 6 9 17l-5-5`,key:`1gmf2c`}]]),ee=O(`chevron-down`,[[`path`,{d:`m6 9 6 6 6-6`,key:`qrunsl`}]]),A=O(`chevron-right`,[[`path`,{d:`m9 18 6-6-6-6`,key:`mthhwq`}]]),j=O(`mail`,[[`path`,{d:`m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7`,key:`132q7q`}],[`rect`,{x:`2`,y:`4`,width:`20`,height:`16`,rx:`2`,key:`izxlao`}]]),M=O(`moon`,[[`path`,{d:`M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401`,key:`kfwtm`}]]),N=O(`radio-tower`,[[`path`,{d:`M4.9 16.1C1 12.2 1 5.8 4.9 1.9`,key:`s0qx1y`}],[`path`,{d:`M7.8 4.7a6.14 6.14 0 0 0-.8 7.5`,key:`1idnkw`}],[`circle`,{cx:`12`,cy:`9`,r:`2`,key:`1092wv`}],[`path`,{d:`M16.2 4.8c2 2 2.26 5.11.8 7.47`,key:`ojru2q`}],[`path`,{d:`M19.1 1.9a9.96 9.96 0 0 1 0 14.1`,key:`rhi7fg`}],[`path`,{d:`M9.5 18h5`,key:`mfy3pd`}],[`path`,{d:`m8 22 4-11 4 11`,key:`25yftu`}]]),P=O(`radio`,[[`path`,{d:`M16.247 7.761a6 6 0 0 1 0 8.478`,key:`1fwjs5`}],[`path`,{d:`M19.075 4.933a10 10 0 0 1 0 14.134`,key:`ehdyv1`}],[`path`,{d:`M4.925 19.067a10 10 0 0 1 0-14.134`,key:`1q22gi`}],[`path`,{d:`M7.753 16.239a6 6 0 0 1 0-8.478`,key:`r2q7qm`}],[`circle`,{cx:`12`,cy:`12`,r:`2`,key:`1c9p78`}]]),F=O(`sun`,[[`circle`,{cx:`12`,cy:`12`,r:`4`,key:`4exip2`}],[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M12 20v2`,key:`1lh1kg`}],[`path`,{d:`m4.93 4.93 1.41 1.41`,key:`149t6j`}],[`path`,{d:`m17.66 17.66 1.41 1.41`,key:`ptbguv`}],[`path`,{d:`M2 12h2`,key:`1t8f8n`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}],[`path`,{d:`m6.34 17.66-1.41 1.41`,key:`1m8zz5`}],[`path`,{d:`m19.07 4.93-1.41 1.41`,key:`1shlcs`}]]),I=O(`webhook`,[[`path`,{d:`M18 16.98h-5.99c-1.1 0-1.95.94-2.48 1.9A4 4 0 0 1 2 17c.01-.7.2-1.4.57-2`,key:`q3hayz`}],[`path`,{d:`m6 17 3.13-5.78c.53-.97.1-2.18-.5-3.1a4 4 0 1 1 6.89-4.06`,key:`1go1hn`}],[`path`,{d:`m12 6 3.13 5.73C15.66 12.7 16.9 13 18 13a4 4 0 0 1 0 8`,key:`qlwsc0`}]]);function te(e){var t,n,r=``;if(typeof e==`string`||typeof e==`number`)r+=e;else if(typeof e==`object`){if(Array.isArray(e)){var i=e.length;for(t=0;t{let n=Array(e.length+t.length);for(let t=0;t({classGroupId:e,validator:t}),L=(e=new Map,t=null,n)=>({nextPart:e,validators:t,classGroupId:n}),R=`-`,ae=[],oe=`arbitrary..`,se=e=>{let t=ue(e),{conflictingClassGroups:n,conflictingClassGroupModifiers:r}=e;return{getClassGroupId:e=>{if(e.startsWith(`[`)&&e.endsWith(`]`))return le(e);let n=e.split(R);return ce(n,+(n[0]===``&&n.length>1),t)},getConflictingClassGroupIds:(e,t)=>{if(t){let t=r[e],i=n[e];return t?i?re(i,t):t:i||ae}return n[e]||ae}}},ce=(e,t,n)=>{if(e.length-t===0)return n.classGroupId;let r=e[t],i=n.nextPart.get(r);if(i){let n=ce(e,t+1,i);if(n)return n}let a=n.validators;if(a===null)return;let o=t===0?e.join(R):e.slice(t).join(R),s=a.length;for(let e=0;ee.slice(1,-1).indexOf(`:`)===-1?void 0:(()=>{let t=e.slice(1,-1),n=t.indexOf(`:`),r=t.slice(0,n);return r?oe+r:void 0})(),ue=e=>{let{theme:t,classGroups:n}=e;return de(n,t)},de=(e,t)=>{let n=L();for(let r in e){let i=e[r];fe(i,n,r,t)}return n},fe=(e,t,n,r)=>{let i=e.length;for(let a=0;a{if(typeof e==`string`){me(e,t,n);return}if(typeof e==`function`){he(e,t,n,r);return}ge(e,t,n,r)},me=(e,t,n)=>{let r=e===``?t:_e(t,e);r.classGroupId=n},he=(e,t,n,r)=>{if(ve(e)){fe(e(r),t,n,r);return}t.validators===null&&(t.validators=[]),t.validators.push(ie(n,e))},ge=(e,t,n,r)=>{let i=Object.entries(e),a=i.length;for(let e=0;e{let n=e,r=t.split(R),i=r.length;for(let e=0;e`isThemeGetter`in e&&e.isThemeGetter===!0,ye=e=>{if(e<1)return{get:()=>void 0,set:()=>{}};let t=0,n=Object.create(null),r=Object.create(null),i=(i,a)=>{n[i]=a,t++,t>e&&(t=0,r=n,n=Object.create(null))};return{get(e){let t=n[e];if(t!==void 0)return t;if((t=r[e])!==void 0)return i(e,t),t},set(e,t){e in n?n[e]=t:i(e,t)}}},be=`!`,xe=`:`,Se=[],Ce=(e,t,n,r,i)=>({modifiers:e,hasImportantModifier:t,baseClassName:n,maybePostfixModifierPosition:r,isExternal:i}),we=e=>{let{prefix:t,experimentalParseClassName:n}=e,r=e=>{let t=[],n=0,r=0,i=0,a,o=e.length;for(let s=0;si?a-i:void 0;return Ce(t,l,c,u)};if(t){let e=t+xe,n=r;r=t=>t.startsWith(e)?n(t.slice(e.length)):Ce(Se,!1,t,void 0,!0)}if(n){let e=r;r=t=>n({className:t,parseClassName:e})}return r},Te=e=>{let t=new Map;return e.orderSensitiveModifiers.forEach((e,n)=>{t.set(e,1e6+n)}),e=>{let n=[],r=[];for(let i=0;i0&&(r.sort(),n.push(...r),r=[]),n.push(a)):r.push(a)}return r.length>0&&(r.sort(),n.push(...r)),n}},Ee=e=>({cache:ye(e.cacheSize),parseClassName:we(e),sortModifiers:Te(e),postfixLookupClassGroupIds:De(e),...se(e)}),De=e=>{let t=Object.create(null),n=e.postfixLookupClassGroups;if(n)for(let e=0;e{let{parseClassName:n,getClassGroupId:r,getConflictingClassGroupIds:i,sortModifiers:a,postfixLookupClassGroupIds:o}=t,s=[],c=e.trim().split(Oe),l=``;for(let e=c.length-1;e>=0;--e){let t=c[e],{isExternal:u,modifiers:d,hasImportantModifier:f,baseClassName:p,maybePostfixModifierPosition:m}=n(t);if(u){l=t+(l.length>0?` `+l:l);continue}let h=!!m,g;if(h){g=r(p.substring(0,m));let e=g&&o[g]?r(p):void 0;e&&e!==g&&(g=e,h=!1)}else g=r(p);if(!g){if(!h){l=t+(l.length>0?` `+l:l);continue}if(g=r(p),!g){l=t+(l.length>0?` `+l:l);continue}h=!1}let _=d.length===0?``:d.length===1?d[0]:a(d).join(`:`),v=f?_+be:_,y=v+g;if(s.indexOf(y)>-1)continue;s.push(y);let b=i(g,h);for(let e=0;e0?` `+l:l)}return l},Ae=(...e)=>{let t=0,n,r,i=``;for(;t{if(typeof e==`string`)return e;let t,n=``;for(let r=0;r{let n,r,i,a,o=o=>(n=Ee(t.reduce((e,t)=>t(e),e())),r=n.cache.get,i=n.cache.set,a=s,s(o)),s=e=>{let t=r(e);if(t)return t;let a=ke(e,n);return i(e,a),a};return a=o,(...e)=>a(Ae(...e))},Ne=[],Pe=e=>{let t=t=>t[e]||Ne;return t.isThemeGetter=!0,t},Fe=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,Ie=/^\((?:(\w[\w-]*):)?(.+)\)$/i,Le=/^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/,Re=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,ze=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,Be=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,Ve=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,He=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,Ue=e=>Le.test(e),z=e=>!!e&&!Number.isNaN(Number(e)),We=e=>!!e&&Number.isInteger(Number(e)),Ge=e=>e.endsWith(`%`)&&z(e.slice(0,-1)),Ke=e=>Re.test(e),qe=()=>!0,Je=e=>ze.test(e)&&!Be.test(e),Ye=()=>!1,Xe=e=>Ve.test(e),Ze=e=>He.test(e),Qe=e=>!B(e)&&!V(e),$e=e=>e.startsWith(`@container`)&&(e[10]===`/`&&e[11]!==void 0||e[11]===`s`&&e[16]!==void 0&&e.startsWith(`-size/`,10)||e[11]===`n`&&e[18]!==void 0&&e.startsWith(`-normal/`,10)),et=e=>ht(e,yt,Ye),B=e=>Fe.test(e),tt=e=>ht(e,bt,Je),nt=e=>ht(e,xt,z),rt=e=>ht(e,Ct,qe),it=e=>ht(e,St,Ye),at=e=>ht(e,_t,Ye),ot=e=>ht(e,vt,Ze),st=e=>ht(e,wt,Xe),V=e=>Ie.test(e),ct=e=>gt(e,bt),lt=e=>gt(e,St),ut=e=>gt(e,_t),dt=e=>gt(e,yt),ft=e=>gt(e,vt),pt=e=>gt(e,wt,!0),mt=e=>gt(e,Ct,!0),ht=(e,t,n)=>{let r=Fe.exec(e);return r?r[1]?t(r[1]):n(r[2]):!1},gt=(e,t,n=!1)=>{let r=Ie.exec(e);return r?r[1]?t(r[1]):n:!1},_t=e=>e===`position`||e===`percentage`,vt=e=>e===`image`||e===`url`,yt=e=>e===`length`||e===`size`||e===`bg-size`,bt=e=>e===`length`,xt=e=>e===`number`,St=e=>e===`family-name`,Ct=e=>e===`number`||e===`weight`,wt=e=>e===`shadow`,Tt=Me(()=>{let e=Pe(`color`),t=Pe(`font`),n=Pe(`text`),r=Pe(`font-weight`),i=Pe(`tracking`),a=Pe(`leading`),o=Pe(`breakpoint`),s=Pe(`container`),c=Pe(`spacing`),l=Pe(`radius`),u=Pe(`shadow`),d=Pe(`inset-shadow`),f=Pe(`text-shadow`),p=Pe(`drop-shadow`),m=Pe(`blur`),h=Pe(`perspective`),g=Pe(`aspect`),_=Pe(`ease`),v=Pe(`animate`),y=()=>[`auto`,`avoid`,`all`,`avoid-page`,`page`,`left`,`right`,`column`],b=()=>[`center`,`top`,`bottom`,`left`,`right`,`top-left`,`left-top`,`top-right`,`right-top`,`bottom-right`,`right-bottom`,`bottom-left`,`left-bottom`],x=()=>[...b(),V,B],S=()=>[`auto`,`hidden`,`clip`,`visible`,`scroll`],C=()=>[`auto`,`contain`,`none`],w=()=>[V,B,c],T=()=>[Ue,`full`,`auto`,...w()],E=()=>[We,`none`,`subgrid`,V,B],D=()=>[`auto`,{span:[`full`,We,V,B]},We,V,B],O=()=>[We,`auto`,V,B],k=()=>[`auto`,`min`,`max`,`fr`,V,B],ee=()=>[`start`,`end`,`center`,`between`,`around`,`evenly`,`stretch`,`baseline`,`center-safe`,`end-safe`],A=()=>[`start`,`end`,`center`,`stretch`,`center-safe`,`end-safe`],j=()=>[`auto`,...w()],M=()=>[Ue,`auto`,`full`,`dvw`,`dvh`,`lvw`,`lvh`,`svw`,`svh`,`min`,`max`,`fit`,...w()],N=()=>[Ue,`screen`,`full`,`dvw`,`lvw`,`svw`,`min`,`max`,`fit`,...w()],P=()=>[Ue,`screen`,`full`,`lh`,`dvh`,`lvh`,`svh`,`min`,`max`,`fit`,...w()],F=()=>[e,V,B],I=()=>[...b(),ut,at,{position:[V,B]}],te=()=>[`no-repeat`,{repeat:[``,`x`,`y`,`space`,`round`]}],ne=()=>[`auto`,`cover`,`contain`,dt,et,{size:[V,B]}],re=()=>[Ge,ct,tt],ie=()=>[``,`none`,`full`,l,V,B],L=()=>[``,z,ct,tt],R=()=>[`solid`,`dashed`,`dotted`,`double`],ae=()=>[`normal`,`multiply`,`screen`,`overlay`,`darken`,`lighten`,`color-dodge`,`color-burn`,`hard-light`,`soft-light`,`difference`,`exclusion`,`hue`,`saturation`,`color`,`luminosity`],oe=()=>[z,Ge,ut,at],se=()=>[``,`none`,m,V,B],ce=()=>[`none`,z,V,B],le=()=>[`none`,z,V,B],ue=()=>[z,V,B],de=()=>[Ue,`full`,...w()];return{cacheSize:500,theme:{animate:[`spin`,`ping`,`pulse`,`bounce`],aspect:[`video`],blur:[Ke],breakpoint:[Ke],color:[qe],container:[Ke],"drop-shadow":[Ke],ease:[`in`,`out`,`in-out`],font:[Qe],"font-weight":[`thin`,`extralight`,`light`,`normal`,`medium`,`semibold`,`bold`,`extrabold`,`black`],"inset-shadow":[Ke],leading:[`none`,`tight`,`snug`,`normal`,`relaxed`,`loose`],perspective:[`dramatic`,`near`,`normal`,`midrange`,`distant`,`none`],radius:[Ke],shadow:[Ke],spacing:[`px`,z],text:[Ke],"text-shadow":[Ke],tracking:[`tighter`,`tight`,`normal`,`wide`,`wider`,`widest`]},classGroups:{aspect:[{aspect:[`auto`,`square`,Ue,B,V,g]}],container:[`container`],"container-type":[{"@container":[``,`normal`,`size`,V,B]}],"container-named":[$e],columns:[{columns:[z,B,V,s]}],"break-after":[{"break-after":y()}],"break-before":[{"break-before":y()}],"break-inside":[{"break-inside":[`auto`,`avoid`,`avoid-page`,`avoid-column`]}],"box-decoration":[{"box-decoration":[`slice`,`clone`]}],box:[{box:[`border`,`content`]}],display:[`block`,`inline-block`,`inline`,`flex`,`inline-flex`,`table`,`inline-table`,`table-caption`,`table-cell`,`table-column`,`table-column-group`,`table-footer-group`,`table-header-group`,`table-row-group`,`table-row`,`flow-root`,`grid`,`inline-grid`,`contents`,`list-item`,`hidden`],sr:[`sr-only`,`not-sr-only`],float:[{float:[`right`,`left`,`none`,`start`,`end`]}],clear:[{clear:[`left`,`right`,`both`,`none`,`start`,`end`]}],isolation:[`isolate`,`isolation-auto`],"object-fit":[{object:[`contain`,`cover`,`fill`,`none`,`scale-down`]}],"object-position":[{object:x()}],overflow:[{overflow:S()}],"overflow-x":[{"overflow-x":S()}],"overflow-y":[{"overflow-y":S()}],overscroll:[{overscroll:C()}],"overscroll-x":[{"overscroll-x":C()}],"overscroll-y":[{"overscroll-y":C()}],position:[`static`,`fixed`,`absolute`,`relative`,`sticky`],inset:[{inset:T()}],"inset-x":[{"inset-x":T()}],"inset-y":[{"inset-y":T()}],start:[{"inset-s":T(),start:T()}],end:[{"inset-e":T(),end:T()}],"inset-bs":[{"inset-bs":T()}],"inset-be":[{"inset-be":T()}],top:[{top:T()}],right:[{right:T()}],bottom:[{bottom:T()}],left:[{left:T()}],visibility:[`visible`,`invisible`,`collapse`],z:[{z:[We,`auto`,V,B]}],basis:[{basis:[Ue,`full`,`auto`,s,...w()]}],"flex-direction":[{flex:[`row`,`row-reverse`,`col`,`col-reverse`]}],"flex-wrap":[{flex:[`nowrap`,`wrap`,`wrap-reverse`]}],flex:[{flex:[z,Ue,`auto`,`initial`,`none`,B]}],grow:[{grow:[``,z,V,B]}],shrink:[{shrink:[``,z,V,B]}],order:[{order:[We,`first`,`last`,`none`,V,B]}],"grid-cols":[{"grid-cols":E()}],"col-start-end":[{col:D()}],"col-start":[{"col-start":O()}],"col-end":[{"col-end":O()}],"grid-rows":[{"grid-rows":E()}],"row-start-end":[{row:D()}],"row-start":[{"row-start":O()}],"row-end":[{"row-end":O()}],"grid-flow":[{"grid-flow":[`row`,`col`,`dense`,`row-dense`,`col-dense`]}],"auto-cols":[{"auto-cols":k()}],"auto-rows":[{"auto-rows":k()}],gap:[{gap:w()}],"gap-x":[{"gap-x":w()}],"gap-y":[{"gap-y":w()}],"justify-content":[{justify:[...ee(),`normal`]}],"justify-items":[{"justify-items":[...A(),`normal`]}],"justify-self":[{"justify-self":[`auto`,...A()]}],"align-content":[{content:[`normal`,...ee()]}],"align-items":[{items:[...A(),{baseline:[``,`last`]}]}],"align-self":[{self:[`auto`,...A(),{baseline:[``,`last`]}]}],"place-content":[{"place-content":ee()}],"place-items":[{"place-items":[...A(),`baseline`]}],"place-self":[{"place-self":[`auto`,...A()]}],p:[{p:w()}],px:[{px:w()}],py:[{py:w()}],ps:[{ps:w()}],pe:[{pe:w()}],pbs:[{pbs:w()}],pbe:[{pbe:w()}],pt:[{pt:w()}],pr:[{pr:w()}],pb:[{pb:w()}],pl:[{pl:w()}],m:[{m:j()}],mx:[{mx:j()}],my:[{my:j()}],ms:[{ms:j()}],me:[{me:j()}],mbs:[{mbs:j()}],mbe:[{mbe:j()}],mt:[{mt:j()}],mr:[{mr:j()}],mb:[{mb:j()}],ml:[{ml:j()}],"space-x":[{"space-x":w()}],"space-x-reverse":[`space-x-reverse`],"space-y":[{"space-y":w()}],"space-y-reverse":[`space-y-reverse`],size:[{size:M()}],"inline-size":[{inline:[`auto`,...N()]}],"min-inline-size":[{"min-inline":[`auto`,...N()]}],"max-inline-size":[{"max-inline":[`none`,...N()]}],"block-size":[{block:[`auto`,...P()]}],"min-block-size":[{"min-block":[`auto`,...P()]}],"max-block-size":[{"max-block":[`none`,...P()]}],w:[{w:[s,`screen`,...M()]}],"min-w":[{"min-w":[s,`screen`,`none`,...M()]}],"max-w":[{"max-w":[s,`screen`,`none`,`prose`,{screen:[o]},...M()]}],h:[{h:[`screen`,`lh`,...M()]}],"min-h":[{"min-h":[`screen`,`lh`,`none`,...M()]}],"max-h":[{"max-h":[`screen`,`lh`,...M()]}],"font-size":[{text:[`base`,n,ct,tt]}],"font-smoothing":[`antialiased`,`subpixel-antialiased`],"font-style":[`italic`,`not-italic`],"font-weight":[{font:[r,mt,rt]}],"font-stretch":[{"font-stretch":[`ultra-condensed`,`extra-condensed`,`condensed`,`semi-condensed`,`normal`,`semi-expanded`,`expanded`,`extra-expanded`,`ultra-expanded`,Ge,B]}],"font-family":[{font:[lt,it,t]}],"font-features":[{"font-features":[B]}],"fvn-normal":[`normal-nums`],"fvn-ordinal":[`ordinal`],"fvn-slashed-zero":[`slashed-zero`],"fvn-figure":[`lining-nums`,`oldstyle-nums`],"fvn-spacing":[`proportional-nums`,`tabular-nums`],"fvn-fraction":[`diagonal-fractions`,`stacked-fractions`],tracking:[{tracking:[i,V,B]}],"line-clamp":[{"line-clamp":[z,`none`,V,nt]}],leading:[{leading:[a,...w()]}],"list-image":[{"list-image":[`none`,V,B]}],"list-style-position":[{list:[`inside`,`outside`]}],"list-style-type":[{list:[`disc`,`decimal`,`none`,V,B]}],"text-alignment":[{text:[`left`,`center`,`right`,`justify`,`start`,`end`]}],"placeholder-color":[{placeholder:F()}],"text-color":[{text:F()}],"text-decoration":[`underline`,`overline`,`line-through`,`no-underline`],"text-decoration-style":[{decoration:[...R(),`wavy`]}],"text-decoration-thickness":[{decoration:[z,`from-font`,`auto`,V,tt]}],"text-decoration-color":[{decoration:F()}],"underline-offset":[{"underline-offset":[z,`auto`,V,B]}],"text-transform":[`uppercase`,`lowercase`,`capitalize`,`normal-case`],"text-overflow":[`truncate`,`text-ellipsis`,`text-clip`],"text-wrap":[{text:[`wrap`,`nowrap`,`balance`,`pretty`]}],indent:[{indent:w()}],"tab-size":[{tab:[We,V,B]}],"vertical-align":[{align:[`baseline`,`top`,`middle`,`bottom`,`text-top`,`text-bottom`,`sub`,`super`,V,B]}],whitespace:[{whitespace:[`normal`,`nowrap`,`pre`,`pre-line`,`pre-wrap`,`break-spaces`]}],break:[{break:[`normal`,`words`,`all`,`keep`]}],wrap:[{wrap:[`break-word`,`anywhere`,`normal`]}],hyphens:[{hyphens:[`none`,`manual`,`auto`]}],content:[{content:[`none`,V,B]}],"bg-attachment":[{bg:[`fixed`,`local`,`scroll`]}],"bg-clip":[{"bg-clip":[`border`,`padding`,`content`,`text`]}],"bg-origin":[{"bg-origin":[`border`,`padding`,`content`]}],"bg-position":[{bg:I()}],"bg-repeat":[{bg:te()}],"bg-size":[{bg:ne()}],"bg-image":[{bg:[`none`,{linear:[{to:[`t`,`tr`,`r`,`br`,`b`,`bl`,`l`,`tl`]},We,V,B],radial:[``,V,B],conic:[We,V,B]},ft,ot]}],"bg-color":[{bg:F()}],"gradient-from-pos":[{from:re()}],"gradient-via-pos":[{via:re()}],"gradient-to-pos":[{to:re()}],"gradient-from":[{from:F()}],"gradient-via":[{via:F()}],"gradient-to":[{to:F()}],rounded:[{rounded:ie()}],"rounded-s":[{"rounded-s":ie()}],"rounded-e":[{"rounded-e":ie()}],"rounded-t":[{"rounded-t":ie()}],"rounded-r":[{"rounded-r":ie()}],"rounded-b":[{"rounded-b":ie()}],"rounded-l":[{"rounded-l":ie()}],"rounded-ss":[{"rounded-ss":ie()}],"rounded-se":[{"rounded-se":ie()}],"rounded-ee":[{"rounded-ee":ie()}],"rounded-es":[{"rounded-es":ie()}],"rounded-tl":[{"rounded-tl":ie()}],"rounded-tr":[{"rounded-tr":ie()}],"rounded-br":[{"rounded-br":ie()}],"rounded-bl":[{"rounded-bl":ie()}],"border-w":[{border:L()}],"border-w-x":[{"border-x":L()}],"border-w-y":[{"border-y":L()}],"border-w-s":[{"border-s":L()}],"border-w-e":[{"border-e":L()}],"border-w-bs":[{"border-bs":L()}],"border-w-be":[{"border-be":L()}],"border-w-t":[{"border-t":L()}],"border-w-r":[{"border-r":L()}],"border-w-b":[{"border-b":L()}],"border-w-l":[{"border-l":L()}],"divide-x":[{"divide-x":L()}],"divide-x-reverse":[`divide-x-reverse`],"divide-y":[{"divide-y":L()}],"divide-y-reverse":[`divide-y-reverse`],"border-style":[{border:[...R(),`hidden`,`none`]}],"divide-style":[{divide:[...R(),`hidden`,`none`]}],"border-color":[{border:F()}],"border-color-x":[{"border-x":F()}],"border-color-y":[{"border-y":F()}],"border-color-s":[{"border-s":F()}],"border-color-e":[{"border-e":F()}],"border-color-bs":[{"border-bs":F()}],"border-color-be":[{"border-be":F()}],"border-color-t":[{"border-t":F()}],"border-color-r":[{"border-r":F()}],"border-color-b":[{"border-b":F()}],"border-color-l":[{"border-l":F()}],"divide-color":[{divide:F()}],"outline-style":[{outline:[...R(),`none`,`hidden`]}],"outline-offset":[{"outline-offset":[z,V,B]}],"outline-w":[{outline:[``,z,ct,tt]}],"outline-color":[{outline:F()}],shadow:[{shadow:[``,`none`,u,pt,st]}],"shadow-color":[{shadow:F()}],"inset-shadow":[{"inset-shadow":[`none`,d,pt,st]}],"inset-shadow-color":[{"inset-shadow":F()}],"ring-w":[{ring:L()}],"ring-w-inset":[`ring-inset`],"ring-color":[{ring:F()}],"ring-offset-w":[{"ring-offset":[z,tt]}],"ring-offset-color":[{"ring-offset":F()}],"inset-ring-w":[{"inset-ring":L()}],"inset-ring-color":[{"inset-ring":F()}],"text-shadow":[{"text-shadow":[`none`,f,pt,st]}],"text-shadow-color":[{"text-shadow":F()}],opacity:[{opacity:[z,V,B]}],"mix-blend":[{"mix-blend":[...ae(),`plus-darker`,`plus-lighter`]}],"bg-blend":[{"bg-blend":ae()}],"mask-clip":[{"mask-clip":[`border`,`padding`,`content`,`fill`,`stroke`,`view`]},`mask-no-clip`],"mask-composite":[{mask:[`add`,`subtract`,`intersect`,`exclude`]}],"mask-image-linear-pos":[{"mask-linear":[z]}],"mask-image-linear-from-pos":[{"mask-linear-from":oe()}],"mask-image-linear-to-pos":[{"mask-linear-to":oe()}],"mask-image-linear-from-color":[{"mask-linear-from":F()}],"mask-image-linear-to-color":[{"mask-linear-to":F()}],"mask-image-t-from-pos":[{"mask-t-from":oe()}],"mask-image-t-to-pos":[{"mask-t-to":oe()}],"mask-image-t-from-color":[{"mask-t-from":F()}],"mask-image-t-to-color":[{"mask-t-to":F()}],"mask-image-r-from-pos":[{"mask-r-from":oe()}],"mask-image-r-to-pos":[{"mask-r-to":oe()}],"mask-image-r-from-color":[{"mask-r-from":F()}],"mask-image-r-to-color":[{"mask-r-to":F()}],"mask-image-b-from-pos":[{"mask-b-from":oe()}],"mask-image-b-to-pos":[{"mask-b-to":oe()}],"mask-image-b-from-color":[{"mask-b-from":F()}],"mask-image-b-to-color":[{"mask-b-to":F()}],"mask-image-l-from-pos":[{"mask-l-from":oe()}],"mask-image-l-to-pos":[{"mask-l-to":oe()}],"mask-image-l-from-color":[{"mask-l-from":F()}],"mask-image-l-to-color":[{"mask-l-to":F()}],"mask-image-x-from-pos":[{"mask-x-from":oe()}],"mask-image-x-to-pos":[{"mask-x-to":oe()}],"mask-image-x-from-color":[{"mask-x-from":F()}],"mask-image-x-to-color":[{"mask-x-to":F()}],"mask-image-y-from-pos":[{"mask-y-from":oe()}],"mask-image-y-to-pos":[{"mask-y-to":oe()}],"mask-image-y-from-color":[{"mask-y-from":F()}],"mask-image-y-to-color":[{"mask-y-to":F()}],"mask-image-radial":[{"mask-radial":[V,B]}],"mask-image-radial-from-pos":[{"mask-radial-from":oe()}],"mask-image-radial-to-pos":[{"mask-radial-to":oe()}],"mask-image-radial-from-color":[{"mask-radial-from":F()}],"mask-image-radial-to-color":[{"mask-radial-to":F()}],"mask-image-radial-shape":[{"mask-radial":[`circle`,`ellipse`]}],"mask-image-radial-size":[{"mask-radial":[{closest:[`side`,`corner`],farthest:[`side`,`corner`]}]}],"mask-image-radial-pos":[{"mask-radial-at":b()}],"mask-image-conic-pos":[{"mask-conic":[z]}],"mask-image-conic-from-pos":[{"mask-conic-from":oe()}],"mask-image-conic-to-pos":[{"mask-conic-to":oe()}],"mask-image-conic-from-color":[{"mask-conic-from":F()}],"mask-image-conic-to-color":[{"mask-conic-to":F()}],"mask-mode":[{mask:[`alpha`,`luminance`,`match`]}],"mask-origin":[{"mask-origin":[`border`,`padding`,`content`,`fill`,`stroke`,`view`]}],"mask-position":[{mask:I()}],"mask-repeat":[{mask:te()}],"mask-size":[{mask:ne()}],"mask-type":[{"mask-type":[`alpha`,`luminance`]}],"mask-image":[{mask:[`none`,V,B]}],filter:[{filter:[``,`none`,V,B]}],blur:[{blur:se()}],brightness:[{brightness:[z,V,B]}],contrast:[{contrast:[z,V,B]}],"drop-shadow":[{"drop-shadow":[``,`none`,p,pt,st]}],"drop-shadow-color":[{"drop-shadow":F()}],grayscale:[{grayscale:[``,z,V,B]}],"hue-rotate":[{"hue-rotate":[z,V,B]}],invert:[{invert:[``,z,V,B]}],saturate:[{saturate:[z,V,B]}],sepia:[{sepia:[``,z,V,B]}],"backdrop-filter":[{"backdrop-filter":[``,`none`,V,B]}],"backdrop-blur":[{"backdrop-blur":se()}],"backdrop-brightness":[{"backdrop-brightness":[z,V,B]}],"backdrop-contrast":[{"backdrop-contrast":[z,V,B]}],"backdrop-grayscale":[{"backdrop-grayscale":[``,z,V,B]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[z,V,B]}],"backdrop-invert":[{"backdrop-invert":[``,z,V,B]}],"backdrop-opacity":[{"backdrop-opacity":[z,V,B]}],"backdrop-saturate":[{"backdrop-saturate":[z,V,B]}],"backdrop-sepia":[{"backdrop-sepia":[``,z,V,B]}],"border-collapse":[{border:[`collapse`,`separate`]}],"border-spacing":[{"border-spacing":w()}],"border-spacing-x":[{"border-spacing-x":w()}],"border-spacing-y":[{"border-spacing-y":w()}],"table-layout":[{table:[`auto`,`fixed`]}],caption:[{caption:[`top`,`bottom`]}],transition:[{transition:[``,`all`,`colors`,`opacity`,`shadow`,`transform`,`none`,V,B]}],"transition-behavior":[{transition:[`normal`,`discrete`]}],duration:[{duration:[z,`initial`,V,B]}],ease:[{ease:[`linear`,`initial`,_,V,B]}],delay:[{delay:[z,V,B]}],animate:[{animate:[`none`,v,V,B]}],backface:[{backface:[`hidden`,`visible`]}],perspective:[{perspective:[h,V,B]}],"perspective-origin":[{"perspective-origin":x()}],rotate:[{rotate:ce()}],"rotate-x":[{"rotate-x":ce()}],"rotate-y":[{"rotate-y":ce()}],"rotate-z":[{"rotate-z":ce()}],scale:[{scale:le()}],"scale-x":[{"scale-x":le()}],"scale-y":[{"scale-y":le()}],"scale-z":[{"scale-z":le()}],"scale-3d":[`scale-3d`],skew:[{skew:ue()}],"skew-x":[{"skew-x":ue()}],"skew-y":[{"skew-y":ue()}],transform:[{transform:[V,B,``,`none`,`gpu`,`cpu`]}],"transform-origin":[{origin:x()}],"transform-style":[{transform:[`3d`,`flat`]}],translate:[{translate:de()}],"translate-x":[{"translate-x":de()}],"translate-y":[{"translate-y":de()}],"translate-z":[{"translate-z":de()}],"translate-none":[`translate-none`],zoom:[{zoom:[We,V,B]}],accent:[{accent:F()}],appearance:[{appearance:[`none`,`auto`]}],"caret-color":[{caret:F()}],"color-scheme":[{scheme:[`normal`,`dark`,`light`,`light-dark`,`only-dark`,`only-light`]}],cursor:[{cursor:[`auto`,`default`,`pointer`,`wait`,`text`,`move`,`help`,`not-allowed`,`none`,`context-menu`,`progress`,`cell`,`crosshair`,`vertical-text`,`alias`,`copy`,`no-drop`,`grab`,`grabbing`,`all-scroll`,`col-resize`,`row-resize`,`n-resize`,`e-resize`,`s-resize`,`w-resize`,`ne-resize`,`nw-resize`,`se-resize`,`sw-resize`,`ew-resize`,`ns-resize`,`nesw-resize`,`nwse-resize`,`zoom-in`,`zoom-out`,V,B]}],"field-sizing":[{"field-sizing":[`fixed`,`content`]}],"pointer-events":[{"pointer-events":[`auto`,`none`]}],resize:[{resize:[`none`,``,`y`,`x`]}],"scroll-behavior":[{scroll:[`auto`,`smooth`]}],"scrollbar-thumb-color":[{"scrollbar-thumb":F()}],"scrollbar-track-color":[{"scrollbar-track":F()}],"scrollbar-gutter":[{"scrollbar-gutter":[`auto`,`stable`,`both`]}],"scrollbar-w":[{scrollbar:[`auto`,`thin`,`none`]}],"scroll-m":[{"scroll-m":w()}],"scroll-mx":[{"scroll-mx":w()}],"scroll-my":[{"scroll-my":w()}],"scroll-ms":[{"scroll-ms":w()}],"scroll-me":[{"scroll-me":w()}],"scroll-mbs":[{"scroll-mbs":w()}],"scroll-mbe":[{"scroll-mbe":w()}],"scroll-mt":[{"scroll-mt":w()}],"scroll-mr":[{"scroll-mr":w()}],"scroll-mb":[{"scroll-mb":w()}],"scroll-ml":[{"scroll-ml":w()}],"scroll-p":[{"scroll-p":w()}],"scroll-px":[{"scroll-px":w()}],"scroll-py":[{"scroll-py":w()}],"scroll-ps":[{"scroll-ps":w()}],"scroll-pe":[{"scroll-pe":w()}],"scroll-pbs":[{"scroll-pbs":w()}],"scroll-pbe":[{"scroll-pbe":w()}],"scroll-pt":[{"scroll-pt":w()}],"scroll-pr":[{"scroll-pr":w()}],"scroll-pb":[{"scroll-pb":w()}],"scroll-pl":[{"scroll-pl":w()}],"snap-align":[{snap:[`start`,`end`,`center`,`align-none`]}],"snap-stop":[{snap:[`normal`,`always`]}],"snap-type":[{snap:[`none`,`x`,`y`,`both`]}],"snap-strictness":[{snap:[`mandatory`,`proximity`]}],touch:[{touch:[`auto`,`none`,`manipulation`]}],"touch-x":[{"touch-pan":[`x`,`left`,`right`]}],"touch-y":[{"touch-pan":[`y`,`up`,`down`]}],"touch-pz":[`touch-pinch-zoom`],select:[{select:[`none`,`text`,`all`,`auto`]}],"will-change":[{"will-change":[`auto`,`scroll`,`contents`,`transform`,V,B]}],fill:[{fill:[`none`,...F()]}],"stroke-w":[{stroke:[z,ct,tt,nt]}],stroke:[{stroke:[`none`,...F()]}],"forced-color-adjust":[{"forced-color-adjust":[`auto`,`none`]}]},conflictingClassGroups:{"container-named":[`container-type`],overflow:[`overflow-x`,`overflow-y`],overscroll:[`overscroll-x`,`overscroll-y`],inset:[`inset-x`,`inset-y`,`inset-bs`,`inset-be`,`start`,`end`,`top`,`right`,`bottom`,`left`],"inset-x":[`right`,`left`],"inset-y":[`top`,`bottom`],flex:[`basis`,`grow`,`shrink`],gap:[`gap-x`,`gap-y`],p:[`px`,`py`,`ps`,`pe`,`pbs`,`pbe`,`pt`,`pr`,`pb`,`pl`],px:[`pr`,`pl`],py:[`pt`,`pb`],m:[`mx`,`my`,`ms`,`me`,`mbs`,`mbe`,`mt`,`mr`,`mb`,`ml`],mx:[`mr`,`ml`],my:[`mt`,`mb`],size:[`w`,`h`],"font-size":[`leading`],"fvn-normal":[`fvn-ordinal`,`fvn-slashed-zero`,`fvn-figure`,`fvn-spacing`,`fvn-fraction`],"fvn-ordinal":[`fvn-normal`],"fvn-slashed-zero":[`fvn-normal`],"fvn-figure":[`fvn-normal`],"fvn-spacing":[`fvn-normal`],"fvn-fraction":[`fvn-normal`],"line-clamp":[`display`,`overflow`],rounded:[`rounded-s`,`rounded-e`,`rounded-t`,`rounded-r`,`rounded-b`,`rounded-l`,`rounded-ss`,`rounded-se`,`rounded-ee`,`rounded-es`,`rounded-tl`,`rounded-tr`,`rounded-br`,`rounded-bl`],"rounded-s":[`rounded-ss`,`rounded-es`],"rounded-e":[`rounded-se`,`rounded-ee`],"rounded-t":[`rounded-tl`,`rounded-tr`],"rounded-r":[`rounded-tr`,`rounded-br`],"rounded-b":[`rounded-br`,`rounded-bl`],"rounded-l":[`rounded-tl`,`rounded-bl`],"border-spacing":[`border-spacing-x`,`border-spacing-y`],"border-w":[`border-w-x`,`border-w-y`,`border-w-s`,`border-w-e`,`border-w-bs`,`border-w-be`,`border-w-t`,`border-w-r`,`border-w-b`,`border-w-l`],"border-w-x":[`border-w-r`,`border-w-l`],"border-w-y":[`border-w-t`,`border-w-b`],"border-color":[`border-color-x`,`border-color-y`,`border-color-s`,`border-color-e`,`border-color-bs`,`border-color-be`,`border-color-t`,`border-color-r`,`border-color-b`,`border-color-l`],"border-color-x":[`border-color-r`,`border-color-l`],"border-color-y":[`border-color-t`,`border-color-b`],translate:[`translate-x`,`translate-y`,`translate-none`],"translate-none":[`translate`,`translate-x`,`translate-y`,`translate-z`],"scroll-m":[`scroll-mx`,`scroll-my`,`scroll-ms`,`scroll-me`,`scroll-mbs`,`scroll-mbe`,`scroll-mt`,`scroll-mr`,`scroll-mb`,`scroll-ml`],"scroll-mx":[`scroll-mr`,`scroll-ml`],"scroll-my":[`scroll-mt`,`scroll-mb`],"scroll-p":[`scroll-px`,`scroll-py`,`scroll-ps`,`scroll-pe`,`scroll-pbs`,`scroll-pbe`,`scroll-pt`,`scroll-pr`,`scroll-pb`,`scroll-pl`],"scroll-px":[`scroll-pr`,`scroll-pl`],"scroll-py":[`scroll-pt`,`scroll-pb`],touch:[`touch-x`,`touch-y`,`touch-pz`],"touch-x":[`touch`],"touch-y":[`touch`],"touch-pz":[`touch`]},conflictingClassGroupModifiers:{"font-size":[`leading`]},postfixLookupClassGroups:[`container-type`],orderSensitiveModifiers:[`*`,`**`,`after`,`backdrop`,`before`,`details-content`,`file`,`first-letter`,`first-line`,`marker`,`placeholder`,`selection`]}});function H(...e){return Tt(ne(e))}var Et=e=>typeof e==`boolean`?`${e}`:e===0?`0`:e,Dt=ne,Ot=(e,t)=>n=>{if(t?.variants==null)return Dt(e,n?.class,n?.className);let{variants:r,defaultVariants:i}=t,a=Object.keys(r).map(e=>{let t=n?.[e],a=i?.[e];if(t===null)return null;let o=Et(t)||Et(a);return r[e][o]}),o=n&&Object.entries(n).reduce((e,t)=>{let[n,r]=t;return r===void 0||(e[n]=r),e},{});return Dt(e,a,t?.compoundVariants?.reduce((e,t)=>{let{class:n,className:r,...a}=t;return Object.entries(a).every(e=>{let[t,n]=e;return Array.isArray(n)?n.includes({...i,...o}[t]):{...i,...o}[t]===n})?[...e,n,r]:e},[]),n?.class,n?.className)},kt=Object.defineProperty,At=(e,t)=>kt(e,`name`,{value:t,configurable:!0});function jt(e,t){if(typeof e==`function`)return e(t);e!=null&&(e.current=t)}At(jt,`setRef`);function Mt(...e){return t=>{let n=!1,r=e.map(e=>{let r=jt(e,t);return!n&&typeof r==`function`&&(n=!0),r});if(n)return()=>{for(let t=0;tFt(e,`name`,{value:t,configurable:!0});function Lt(e){let t=_.forwardRef((t,n)=>{let{children:r,...i}=t,a=null,o=!1,s=[];Kt(r)&&typeof Xt==`function`&&(r=Xt(r._payload)),_.Children.forEach(r,e=>{if(Wt(e)){o=!0;let t=e,n=`child`in t.props?t.props.child:t.props.children;Kt(n)&&typeof Xt==`function`&&(n=Xt(n._payload)),a=Vt(t,n),s.push(a?.props?.children)}else s.push(e)}),a?a=_.cloneElement(a,void 0,s):!o&&_.Children.count(r)===1&&_.isValidElement(r)&&(a=r);let c=a?Ut(a):void 0,l=Nt(n,c);if(!a){if(r||r===0)throw Error(o?Yt(e):Jt(e));return r}let u=Ht(i,a.props??{});return a.type!==_.Fragment&&(u.ref=n?l:c),_.cloneElement(a,u)});return t.displayName=`${e}.Slot`,t}It(Lt,`createSlot`);var Rt=Lt(`Slot`),zt=Symbol.for(`radix.slottable`);function Bt(e){let t=It(e=>`child`in e?e.children(e.child):e.children,`Slottable`);return t.displayName=`${e}.Slottable`,t.__radixId=zt,t}It(Bt,`createSlottable`);var Vt=It((e,t)=>{if(`child`in e.props){let t=e.props.child;return _.isValidElement(t)?_.cloneElement(t,void 0,e.props.children(t.props.children)):null}return _.isValidElement(t)?t:null},`getSlottableElementFromSlottable`);function Ht(e,t){let n={...t};for(let r in t){let i=e[r],a=t[r];/^on[A-Z]/.test(r)?i&&a?n[r]=(...e)=>{let t=a(...e);return i(...e),t}:i&&(n[r]=i):r===`style`?n[r]={...i,...a}:r===`className`&&(n[r]=[i,a].filter(Boolean).join(` `))}return{...e,...n}}It(Ht,`mergeProps`);function Ut(e){let t=Object.getOwnPropertyDescriptor(e.props,`ref`)?.get,n=t&&`isReactWarning`in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,`ref`)?.get,n=t&&`isReactWarning`in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}It(Ut,`getElementRef`);function Wt(e){return _.isValidElement(e)&&typeof e.type==`function`&&`__radixId`in e.type&&e.type.__radixId===zt}It(Wt,`isSlottable`);var Gt=Symbol.for(`react.lazy`);function Kt(e){return typeof e==`object`&&!!e&&`$$typeof`in e&&e.$$typeof===Gt&&`_payload`in e&&qt(e._payload)}It(Kt,`isLazyComponent`);function qt(e){return typeof e==`object`&&!!e&&`then`in e}It(qt,`isPromiseLike`);var Jt=It(e=>`${e} failed to slot onto its children. Expected a single React element child or \`Slottable\`.`,`createSlotError`),Yt=It(e=>`${e} failed to slot onto its \`Slottable\`. Expected \`Slottable\` to receive a single React element child.`,`createSlottableError`),Xt=_.use,Zt=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),U=o(((e,t)=>{t.exports=Zt()}))(),Qt=Object.defineProperty,$t=(e,t)=>Qt(e,`name`,{value:t,configurable:!0}),W=[`a`,`button`,`div`,`form`,`h2`,`h3`,`img`,`input`,`label`,`li`,`nav`,`ol`,`p`,`select`,`span`,`svg`,`ul`].reduce((e,t)=>{let n=Lt(`Primitive.${t}`),r=_.forwardRef((e,r)=>{let{asChild:i,...a}=e,o=i?n:t;return typeof window<`u`&&(window[Symbol.for(`radix-ui`)]=!0),(0,U.jsx)(o,{...a,ref:r})});return r.displayName=`Primitive.${t}`,{...e,[t]:r}},{});function en(e,t){e&&Pt.flushSync(()=>e.dispatchEvent(t))}$t(en,`dispatchDiscreteCustomEvent`);var tn=Object.defineProperty,nn=(e,t)=>tn(e,`name`,{value:t,configurable:!0}),rn=Object.freeze({position:`absolute`,border:0,width:1,height:1,padding:0,margin:-1,overflow:`hidden`,clip:`rect(0, 0, 0, 0)`,whiteSpace:`nowrap`,wordWrap:`normal`}),an=_.forwardRef(nn(function(e,t){return(0,U.jsx)(W.span,{...e,ref:t,style:{...rn,...e.style}})},`VisuallyHidden`)),on=Object.defineProperty,sn=(e,t)=>on(e,`name`,{value:t,configurable:!0});function cn(e,t){let n=_.createContext(t);n.displayName=e+`Context`;let r=sn(e=>{let{children:t,...r}=e,i=_.useMemo(()=>r,Object.values(r));return(0,U.jsx)(n.Provider,{value:i,children:t})},`Provider`);r.displayName=e+`Provider`;function i(r,i={}){let{optional:a=!1}=i,o=_.useContext(n);if(o)return o;if(t!==void 0)return t;if(!a)throw Error(`\`${r}\` must be used within \`${e}\``)}return sn(i,`useContext`),[r,i]}sn(cn,`createContext`);function ln(e,t=[]){let n=[];function r(t,r){let i=_.createContext(r);i.displayName=t+`Context`;let a=n.length;n=[...n,r];let o=sn(t=>{let{scope:n,children:r,...o}=t,s=n?.[e]?.[a]||i,c=_.useMemo(()=>o,Object.values(o));return(0,U.jsx)(s.Provider,{value:c,children:r})},`Provider`);o.displayName=t+`Provider`;function s(n,o,s={}){let{optional:c=!1}=s,l=o?.[e]?.[a]||i,u=_.useContext(l);if(u)return u;if(r!==void 0)return r;if(!c)throw Error(`\`${n}\` must be used within \`${t}\``)}return sn(s,`useContext`),[o,s]}sn(r,`createContext`);let i=sn(()=>{let t=n.map(e=>_.createContext(e));return sn(function(n){let r=n?.[e]||t;return _.useMemo(()=>({[`__scope${e}`]:{...n,[e]:r}}),[n,r])},`useScope`)},`createScope`);return i.scopeName=e,[r,un(i,...t)]}sn(ln,`createContextScope`);function un(...e){let t=e[0];if(e.length===1)return t;let n=sn(()=>{let n=e.map(e=>({useScope:e(),scopeName:e.scopeName}));return sn(function(e){let r=n.reduce((t,{useScope:n,scopeName:r})=>{let i=n(e)[`__scope${r}`];return{...t,...i}},{});return _.useMemo(()=>({[`__scope${t.scopeName}`]:r}),[r])},`useComposedScopes`)},`createScope`);return n.scopeName=t.scopeName,n}sn(un,`composeContextScopes`);var dn=Object.defineProperty,fn=(e,t)=>dn(e,`name`,{value:t,configurable:!0});function pn(e){let t=e+`CollectionProvider`,[n,r]=ln(t),[i,a]=n(t,{collectionRef:{current:null},itemMap:new Map}),o=fn(e=>{let{scope:t,children:n}=e,r=_.useRef(null),a=_.useRef(new Map).current;return(0,U.jsx)(i,{scope:t,itemMap:a,collectionRef:r,children:n})},`CollectionProvider`);o.displayName=t;let s=e+`CollectionSlot`,c=Lt(s),l=_.forwardRef((e,t)=>{let{scope:n,children:r}=e,i=Nt(t,a(s,n).collectionRef);return(0,U.jsx)(c,{ref:i,children:r})});l.displayName=s;let u=e+`CollectionItemSlot`,d=`data-radix-collection-item`,f=Lt(u),p=_.forwardRef((e,t)=>{let{scope:n,children:r,...i}=e,o=_.useRef(null),s=Nt(t,o),c=a(u,n);return _.useEffect(()=>(c.itemMap.set(o,{ref:o,...i}),()=>void c.itemMap.delete(o))),(0,U.jsx)(f,{[d]:``,ref:s,children:r})});p.displayName=u;function m(t){let n=a(e+`CollectionConsumer`,t);return _.useCallback(()=>{let e=n.collectionRef.current;if(!e)return[];let t=Array.from(e.querySelectorAll(`[${d}]`));return Array.from(n.itemMap.values()).sort((e,n)=>t.indexOf(e.ref.current)-t.indexOf(n.ref.current))},[n.collectionRef,n.itemMap])}return fn(m,`useCollection`),[{Provider:o,Slot:l,ItemSlot:p},m,r]}fn(pn,`createCollection`);var mn=new WeakMap,hn=class e extends Map{static{fn(this,`OrderedDict`)}#e;constructor(e){super(e),this.#e=[...super.keys()],mn.set(this,!0)}set(e,t){return mn.get(this)&&(this.has(e)?this.#e[this.#e.indexOf(e)]=e:this.#e.push(e)),super.set(e,t),this}insert(e,t,n){let r=this.has(t),i=this.#e.length,a=vn(e),o=a>=0?a:i+a,s=o<0||o>=i?-1:o;if(s===this.size||r&&s===this.size-1||s===-1)return this.set(t,n),this;let c=this.size+ +!r;a<0&&o++;let l=[...this.#e],u,d=!1;for(let e=o;e=this.size&&(r=this.size-1),this.at(r)}keyFrom(e,t){let n=this.indexOf(e);if(n===-1)return;let r=n+t;return r<0&&(r=0),r>=this.size&&(r=this.size-1),this.keyAt(r)}find(e,t){let n=0;for(let r of this){if(Reflect.apply(e,t,[r,n,this]))return r;n++}}findIndex(e,t){let n=0;for(let r of this){if(Reflect.apply(e,t,[r,n,this]))return n;n++}return-1}filter(t,n){let r=[],i=0;for(let e of this)Reflect.apply(t,n,[e,i,this])&&r.push(e),i++;return new e(r)}map(t,n){let r=[],i=0;for(let e of this)r.push([e[0],Reflect.apply(t,n,[e,i,this])]),i++;return new e(r)}reduce(...e){let[t,n]=e,r=0,i=n??this.at(0);for(let n of this)i=r===0&&e.length===1?n:Reflect.apply(t,this,[i,n,r,this]),r++;return i}reduceRight(...e){let[t,n]=e,r=n??this.at(-1);for(let n=this.size-1;n>=0;n--){let i=this.at(n);r=n===this.size-1&&e.length===1?i:Reflect.apply(t,this,[r,i,n,this])}return r}toSorted(t){let n=[...this.entries()].sort(t);return new e(n)}toReversed(){let t=new e;for(let e=this.size-1;e>=0;e--){let n=this.keyAt(e),r=this.get(n);t.set(n,r)}return t}toSpliced(...t){let n=[...this.entries()];return n.splice(...t),new e(n)}slice(t,n){let r=new e,i=this.size-1;if(t===void 0)return r;t<0&&(t+=this.size),n!==void 0&&n>0&&(i=n-1);for(let e=t;e<=i;e++){let t=this.keyAt(e),n=this.get(t);r.set(t,n)}return r}every(e,t){let n=0;for(let r of this){if(!Reflect.apply(e,t,[r,n,this]))return!1;n++}return!0}some(e,t){let n=0;for(let r of this){if(Reflect.apply(e,t,[r,n,this]))return!0;n++}return!1}};function gn(e,t){if(`at`in Array.prototype)return Array.prototype.at.call(e,t);let n=_n(e,t);return n===-1?void 0:e[n]}fn(gn,`at`);function _n(e,t){let n=e.length,r=vn(t),i=r>=0?r:n+r;return i<0||i>=n?-1:i}fn(_n,`toSafeIndex`);function vn(e){return e!==e||e===0?0:Math.trunc(e)}fn(vn,`toSafeInteger`);function yn(e){let t=e+`CollectionProvider`,[n,r]=ln(t),[i,a]=n(t,{collectionElement:null,collectionRef:{current:null},collectionRefObject:{current:null},itemMap:new hn,setItemMap:fn(()=>void 0,`setItemMap`)}),o=fn(({state:e,...t})=>e?(0,U.jsx)(c,{...t,state:e}):(0,U.jsx)(s,{...t}),`CollectionProvider`);o.displayName=t;let s=fn(e=>{let t=h();return(0,U.jsx)(c,{...e,state:t})},`CollectionInit`);s.displayName=t+`Init`;let c=fn(e=>{let{scope:t,children:n,state:r}=e,a=_.useRef(null),[o,s]=_.useState(null),c=Nt(a,s),[l,u]=r;return _.useEffect(()=>{if(!o)return;let e=Cn(()=>{});return e.observe(o,{childList:!0,subtree:!0}),()=>{e.disconnect()}},[o]),(0,U.jsx)(i,{scope:t,itemMap:l,setItemMap:u,collectionRef:c,collectionRefObject:a,collectionElement:o,children:n})},`CollectionProviderImpl`);c.displayName=t+`Impl`;let l=e+`CollectionSlot`,u=Lt(l),d=_.forwardRef((e,t)=>{let{scope:n,children:r}=e,i=Nt(t,a(l,n).collectionRef);return(0,U.jsx)(u,{ref:i,children:r})});d.displayName=l;let f=e+`CollectionItemSlot`,p=Lt(f),m=_.forwardRef((e,t)=>{let{scope:n,children:r,...i}=e,o=_.useRef(null),[s,c]=_.useState(null),l=Nt(t,o,c),{setItemMap:u}=a(f,n),d=_.useRef(i);bn(d.current,i)||(d.current=i);let m=d.current;return _.useEffect(()=>{let e=m;return u(t=>s?t.has(s)?t.set(s,{...e,element:s}).toSorted(Sn):(t.set(s,{...e,element:s}),t.toSorted(Sn)):t),()=>{u(e=>!s||!e.has(s)?e:(e.delete(s),new hn(e)))}},[s,m,u]),(0,U.jsx)(p,{"data-radix-collection-item":``,ref:l,children:r})});m.displayName=f;function h(){return _.useState(new hn)}fn(h,`useInitCollection`);function g(t){let{itemMap:n}=a(e+`CollectionConsumer`,t);return n}return fn(g,`useCollection`),[{Provider:o,Slot:d,ItemSlot:m},{createCollectionScope:r,useCollection:g,useInitCollection:h}]}fn(yn,`createCollection`);function bn(e,t){if(e===t)return!0;if(typeof e!=`object`||typeof t!=`object`||e==null||t==null)return!1;let n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(let r of n)if(!Object.prototype.hasOwnProperty.call(t,r)||e[r]!==t[r])return!1;return!0}fn(bn,`shallowEqual`);function xn(e,t){return!!(t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_PRECEDING)}fn(xn,`isElementPreceding`);function Sn(e,t){return!e[1].element||!t[1].element?0:xn(e[1].element,t[1].element)?-1:1}fn(Sn,`sortByDocumentPosition`);function Cn(e){return new MutationObserver(t=>{for(let n of t)if(n.type===`childList`){e();return}})}fn(Cn,`getChildListObserver`);var wn=Object.defineProperty,Tn=(e,t)=>wn(e,`name`,{value:t,configurable:!0}),En=!!(typeof window<`u`&&window.document&&window.document.createElement);function G(e,t,{checkForDefaultPrevented:n=!0}={}){return Tn(function(r){if(e?.(r),n===!1||!r||!r.defaultPrevented)return t?.(r)},`handleEvent`)}Tn(G,`composeEventHandlers`);function Dn(e){if(!En)throw Error(`Cannot access window outside of the DOM`);return e?.ownerDocument?.defaultView??window}Tn(Dn,`getOwnerWindow`);function On(e){if(!En)throw Error(`Cannot access document outside of the DOM`);return e?.ownerDocument??document}Tn(On,`getOwnerDocument`);function kn(e,t=!1){let{activeElement:n}=On(e);if(!n?.nodeName)return null;if(An(n)&&n.contentDocument)return kn(n.contentDocument.body,t);if(t){let e=n.getAttribute(`aria-activedescendant`);if(e){let t=On(n).getElementById(e);if(t)return t}}return n}Tn(kn,`getActiveElement`);function An(e){return e.tagName===`IFRAME`}Tn(An,`isFrame`);var jn=globalThis?.document?_.useLayoutEffect:()=>{},Mn=Object.defineProperty,Nn=(e,t)=>Mn(e,`name`,{value:t,configurable:!0}),Pn=_.useEffectEvent,Fn=_.useInsertionEffect;function In(e){if(typeof Pn==`function`)return Pn(e);let t=_.useRef(()=>{throw Error(`Cannot call an event handler while rendering.`)});return typeof Fn==`function`?Fn(()=>{t.current=e}):jn(()=>{t.current=e}),_.useMemo(()=>((...e)=>t.current?.(...e)),[])}Nn(In,`useEffectEvent`);var Ln=Object.defineProperty,Rn=(e,t)=>Ln(e,`name`,{value:t,configurable:!0}),zn=_.useInsertionEffect||jn;function Bn({prop:e,defaultProp:t,onChange:n=Rn(()=>{},`onChange`),caller:r}){let[i,a,o]=Vn({defaultProp:t,onChange:n}),s=e!==void 0;return[s?e:i,_.useCallback(t=>{if(s){let n=Hn(t)?t(e):t;n!==e&&o.current?.(n)}else a(t)},[s,e,a,o])]}Rn(Bn,`useControllableState`);function Vn({defaultProp:e,onChange:t}){let[n,r]=_.useState(e),i=_.useRef(n),a=_.useRef(t);return zn(()=>{a.current=t},[t]),_.useEffect(()=>{i.current!==n&&(a.current?.(n),i.current=n)},[n,i]),[n,r,a]}Rn(Vn,`useUncontrolledState`);function Hn(e){return typeof e==`function`}Rn(Hn,`isFunction`);var Un=Symbol(`RADIX:SYNC_STATE`);function Wn(e,t,n,r){let{prop:i,defaultProp:a,onChange:o,caller:s}=t,c=i!==void 0,l=In(o),u=[{...n,state:a}];r&&u.push(r);let[d,f]=_.useReducer((t,n)=>{if(n.type===Un)return{...t,state:n.state};let r=e(t,n);return c&&!Object.is(r.state,t.state)&&l(r.state),r},...u),p=d.state,m=_.useRef(p);_.useEffect(()=>{m.current!==p&&(m.current=p,c||l(p))},[p,m,c]);let h=_.useMemo(()=>i===void 0?d:{...d,state:i},[d,i]);return _.useEffect(()=>{c&&!Object.is(i,d.state)&&f({type:Un,state:i})},[i,d.state,c]),[h,f]}Rn(Wn,`useControllableStateReducer`);var Gn=Object.defineProperty,Kn=(e,t)=>Gn(e,`name`,{value:t,configurable:!0});function qn(e,t){return _.useReducer((e,n)=>t[e][n]??e,e)}Kn(qn,`useStateMachine`);var Jn=Kn(e=>{let{present:t,children:n}=e,r=Yn(t),i=typeof n==`function`?n({present:r.isPresent}):_.Children.only(n),a=Zn(r.ref,$n(i));return typeof n==`function`||r.isPresent?_.cloneElement(i,{ref:a}):null},`Presence`);function Yn(e){let[t,n]=_.useState(),r=_.useRef(null),i=_.useRef(e),a=_.useRef(`none`),o=_.useRef(void 0),[s,c]=qn(e?`mounted`:`unmounted`,{mounted:{UNMOUNT:`unmounted`,ANIMATION_OUT:`unmountSuspended`},unmountSuspended:{MOUNT:`mounted`,ANIMATION_END:`unmounted`},unmounted:{MOUNT:`mounted`}});return _.useEffect(()=>{s===`mounted`?(a.current=o.current??Qn(r.current),o.current=void 0):a.current=`none`},[s]),jn(()=>{let t=r.current,n=i.current;if(n!==e){let r=a.current,s=Qn(t);e?(o.current=s,c(`MOUNT`)):s===`none`||t?.display===`none`?c(`UNMOUNT`):c(n&&r!==s?`ANIMATION_OUT`:`UNMOUNT`),i.current=e}},[e,c]),jn(()=>{if(t){let e,n=t.ownerDocument.defaultView??window,o=Kn(a=>{let o=Qn(r.current).includes(CSS.escape(a.animationName));if(a.target===t&&o&&(c(`ANIMATION_END`),!i.current)){let r=t.style.animationFillMode;t.style.animationFillMode=`forwards`,e=n.setTimeout(()=>{t.style.animationFillMode===`forwards`&&(t.style.animationFillMode=r)})}},`handleAnimationEnd`),s=Kn(e=>{e.target===t&&(a.current=Qn(r.current))},`handleAnimationStart`);return t.addEventListener(`animationstart`,s),t.addEventListener(`animationcancel`,o),t.addEventListener(`animationend`,o),()=>{n.clearTimeout(e),t.removeEventListener(`animationstart`,s),t.removeEventListener(`animationcancel`,o),t.removeEventListener(`animationend`,o)}}c(`ANIMATION_END`)},[t,c]),{isPresent:[`mounted`,`unmountSuspended`].includes(s),ref:_.useCallback(e=>{if(e){let t=getComputedStyle(e);r.current=t,o.current=Qn(t)}else r.current=null;n(e)},[])}}Kn(Yn,`usePresence`);function Xn(e,t){if(typeof e==`function`)return e(t);e!=null&&(e.current=t)}Kn(Xn,`setRef`);function Zn(...e){let t=_.useRef(e);return t.current=e,_.useCallback(e=>{let n=t.current,r=!1,i=n.map(t=>{let n=Xn(t,e);return!r&&typeof n==`function`&&(r=!0),n});if(r)return()=>{for(let e=0;eer(e,`name`,{value:t,configurable:!0}),nr=_.useId||(()=>void 0),rr=0;function ir(e){let[t,n]=_.useState(nr());return jn(()=>{e||n(e=>e??String(rr++))},[e]),e||(t?`radix-${t}`:``)}tr(ir,`useId`);var ar=Object.defineProperty,or=(e,t)=>ar(e,`name`,{value:t,configurable:!0}),sr=`Collapsible`,[cr,lr]=ln(sr),[ur,dr]=cr(sr),fr=_.forwardRef(or(function(e,t){let{__scopeCollapsible:n,open:r,defaultOpen:i,disabled:a,onOpenChange:o,...s}=e,[c,l]=Bn({prop:r,defaultProp:i??!1,onChange:o,caller:sr});return(0,U.jsx)(ur,{scope:n,disabled:a,contentId:ir(),open:c,onOpenToggle:_.useCallback(()=>l(e=>!e),[l]),children:(0,U.jsx)(W.div,{"data-state":vr(c),"data-disabled":a?``:void 0,...s,ref:t})})},`Collapsible`)),pr=`CollapsibleTrigger`,mr=_.forwardRef(or(function(e,t){let{__scopeCollapsible:n,...r}=e,i=dr(pr,n);return(0,U.jsx)(W.button,{type:`button`,"aria-controls":i.open?i.contentId:void 0,"aria-expanded":i.open||!1,"data-state":vr(i.open),"data-disabled":i.disabled?``:void 0,disabled:i.disabled,...r,ref:t,onClick:G(e.onClick,i.onOpenToggle)})},`CollapsibleTrigger`)),hr=`CollapsibleContent`,gr=_.forwardRef(or(function(e,t){let{forceMount:n,...r}=e,i=dr(hr,e.__scopeCollapsible);return(0,U.jsx)(Jn,{present:n||i.open,children:({present:e})=>(0,U.jsx)(_r,{...r,ref:t,present:e})})},`CollapsibleContent`)),_r=_.forwardRef(or(function(e,t){let{__scopeCollapsible:n,present:r,children:i,...a}=e,o=dr(hr,n),[s,c]=_.useState(r),l=_.useRef(null),u=Nt(t,l),d=_.useRef(0),f=d.current,p=_.useRef(0),m=p.current,h=o.open||s,g=_.useRef(h),v=_.useRef(void 0);return _.useEffect(()=>{let e=requestAnimationFrame(()=>g.current=!1);return()=>cancelAnimationFrame(e)},[]),jn(()=>{let e=l.current;if(e){v.current=v.current||{transitionDuration:e.style.transitionDuration,animationName:e.style.animationName},e.style.transitionDuration=`0s`,e.style.animationName=`none`;let t=e.getBoundingClientRect();d.current=t.height,p.current=t.width,g.current||(e.style.transitionDuration=v.current.transitionDuration,e.style.animationName=v.current.animationName),c(r)}},[o.open,r]),(0,U.jsx)(W.div,{"data-state":vr(o.open),"data-disabled":o.disabled?``:void 0,id:o.contentId,hidden:!h,...a,ref:u,style:{"--radix-collapsible-content-height":f?`${f}px`:void 0,"--radix-collapsible-content-width":m?`${m}px`:void 0,...e.style},children:h&&i})},`CollapsibleContentImpl`));function vr(e){return e?`open`:`closed`}or(vr,`getState`);var yr=fr,br=Object.defineProperty,xr=(e,t)=>br(e,`name`,{value:t,configurable:!0}),Sr=_.createContext(void 0);function Cr(e){let t=_.useContext(Sr);return e||t||`ltr`}xr(Cr,`useDirection`);var wr=Object.defineProperty,Tr=(e,t)=>wr(e,`name`,{value:t,configurable:!0});function Er(e){let t=_.useRef(e);return _.useEffect(()=>{t.current=e}),_.useMemo(()=>((...e)=>t.current?.(...e)),[])}Tr(Er,`useCallbackRef`);var Dr=Object.defineProperty,Or=(e,t)=>Dr(e,`name`,{value:t,configurable:!0}),kr=`dismissableLayer.update`,Ar=`dismissableLayer.pointerDownOutside`,jr=`dismissableLayer.focusOutside`,Mr,Nr=_.createContext({layers:new Set,layersWithOutsidePointerEventsDisabled:new Set,branches:new Set,dismissableSurfaces:new Set}),Pr=_.forwardRef(Or(function(e,t){let{disableOutsidePointerEvents:n=!1,deferPointerDownOutside:r=!1,onEscapeKeyDown:i,onPointerDownOutside:a,onFocusOutside:o,onInteractOutside:s,onDismiss:c,...l}=e,u=_.useContext(Nr),[d,f]=_.useState(null),p=d?.ownerDocument??globalThis?.document,[,m]=_.useState({}),h=Nt(t,f),g=Array.from(u.layers),[v]=[...u.layersWithOutsidePointerEventsDisabled].slice(-1),y=v?g.indexOf(v):-1,b=d?g.indexOf(d):-1,x=u.layersWithOutsidePointerEventsDisabled.size>0,S=b>=y,C=_.useRef(!1),w=Lr(e=>{a?.(e),s?.(e),e.defaultPrevented||c?.()},{ownerDocument:p,deferPointerDownOutside:r,isDeferredPointerDownOutsideRef:C,dismissableSurfaces:u.dismissableSurfaces,shouldHandlePointerDownOutside:_.useCallback(e=>{if(!(e instanceof Node))return!1;let t=[...u.branches].some(t=>t.contains(e));return S&&!t},[u.branches,S])}),T=Rr(e=>{if(r&&C.current)return;let t=e.target;[...u.branches].some(e=>e.contains(t))||(o?.(e),s?.(e),e.defaultPrevented||c?.())},p),E=d?b===g.length-1:!1,D=Er(e=>{e.key===`Escape`&&(i?.(e),!e.defaultPrevented&&c&&(e.preventDefault(),c()))});return _.useEffect(()=>{if(E)return p.addEventListener(`keydown`,D,{capture:!0}),()=>p.removeEventListener(`keydown`,D,{capture:!0})},[p,E,D]),_.useEffect(()=>{if(d)return n&&(u.layersWithOutsidePointerEventsDisabled.size===0&&(Mr=p.body.style.pointerEvents,p.body.style.pointerEvents=`none`),u.layersWithOutsidePointerEventsDisabled.add(d)),u.layers.add(d),zr(),()=>{n&&(u.layersWithOutsidePointerEventsDisabled.delete(d),u.layersWithOutsidePointerEventsDisabled.size===0&&(p.body.style.pointerEvents=Mr))}},[d,p,n,u]),_.useEffect(()=>()=>{d&&(u.layers.delete(d),u.layersWithOutsidePointerEventsDisabled.delete(d),zr())},[d,u]),_.useEffect(()=>{let e=Or(()=>m({}),`handleUpdate`);return document.addEventListener(kr,e),()=>document.removeEventListener(kr,e)},[]),(0,U.jsx)(W.div,{...l,ref:h,style:{pointerEvents:x?S?`auto`:`none`:void 0,...e.style},onFocusCapture:G(e.onFocusCapture,T.onFocusCapture),onBlurCapture:G(e.onBlurCapture,T.onBlurCapture),onPointerDownCapture:G(e.onPointerDownCapture,w.onPointerDownCapture)})},`DismissableLayer`));function Fr(){let e=_.useContext(Nr),[t,n]=_.useState(null);return _.useEffect(()=>{if(t)return e.dismissableSurfaces.add(t),()=>{e.dismissableSurfaces.delete(t)}},[t,e.dismissableSurfaces]),n}Or(Fr,`useDismissableLayerSurface`);var Ir=Or(()=>!0,`IS_TRUE`);function Lr(e,t){let{ownerDocument:n=globalThis?.document,deferPointerDownOutside:r=!1,isDeferredPointerDownOutsideRef:i,dismissableSurfaces:a,shouldHandlePointerDownOutside:o=Ir}=t,s=Er(e),c=_.useRef(!1),l=_.useRef(!1),u=_.useRef(new Map),d=_.useRef(()=>{});return _.useEffect(()=>{function e(){l.current=!1,i.current=!1,u.current.clear()}Or(e,`resetOutsideInteraction`);function t(){return Array.from(u.current.values()).some(Boolean)}Or(t,`isOutsideInteractionIntercepted`);function f(e){if(!l.current)return;let t=e.target;t instanceof Node&&[...a].some(e=>e.contains(t))||u.current.set(e.type,!0),e.type===`click`&&window.setTimeout(()=>{l.current&&d.current()},0)}Or(f,`handleInteractionCapture`);function p(e){l.current&&u.current.set(e.type,!1)}Or(p,`handleInteractionBubble`);let m=Or(a=>{if(a.target&&!c.current){let f=function(){n.removeEventListener(`click`,d.current);let r=t();e(),r||Br(Ar,s,p,{discrete:!0})};if(Or(f,`handleAndDispatchPointerDownOutsideEvent`),!o(a.target)){n.removeEventListener(`click`,d.current),e(),c.current=!1;return}let p={originalEvent:a};l.current=!0,i.current=r&&a.button===0,u.current.clear(),!r||a.button!==0?f():(n.removeEventListener(`click`,d.current),d.current=f,n.addEventListener(`click`,d.current,{once:!0}))}else n.removeEventListener(`click`,d.current),e();c.current=!1},`handlePointerDown`),h=[`pointerup`,`mousedown`,`mouseup`,`touchstart`,`touchend`,`click`];for(let e of h)n.addEventListener(e,f,!0),n.addEventListener(e,p);let g=window.setTimeout(()=>{n.addEventListener(`pointerdown`,m)},0);return()=>{window.clearTimeout(g),n.removeEventListener(`pointerdown`,m),n.removeEventListener(`click`,d.current);for(let e of h)n.removeEventListener(e,f,!0),n.removeEventListener(e,p)}},[n,s,r,i,a,o]),{onPointerDownCapture:Or(()=>c.current=!0,`onPointerDownCapture`)}}Or(Lr,`usePointerDownOutside`);function Rr(e,t=globalThis?.document){let n=Er(e),r=_.useRef(!1);return _.useEffect(()=>{let e=Or(e=>{e.target&&!r.current&&Br(jr,n,{originalEvent:e},{discrete:!1})},`handleFocus`);return t.addEventListener(`focusin`,e),()=>t.removeEventListener(`focusin`,e)},[t,n]),{onFocusCapture:Or(()=>r.current=!0,`onFocusCapture`),onBlurCapture:Or(()=>r.current=!1,`onBlurCapture`)}}Or(Rr,`useFocusOutside`);function zr(){let e=new CustomEvent(kr);document.dispatchEvent(e)}Or(zr,`dispatchUpdate`);function Br(e,t,n,{discrete:r}){let i=n.originalEvent.target,a=new CustomEvent(e,{bubbles:!1,cancelable:!0,detail:n});t&&i.addEventListener(e,t,{once:!0}),r?en(i,a):i.dispatchEvent(a)}Or(Br,`handleAndDispatchCustomEvent`);var Vr=Object.defineProperty,Hr=(e,t)=>Vr(e,`name`,{value:t,configurable:!0}),Ur=`focusScope.autoFocusOnMount`,Wr=`focusScope.autoFocusOnUnmount`,Gr={bubbles:!1,cancelable:!0},Kr=_.forwardRef(Hr(function(e,t){let{loop:n=!1,trapped:r=!1,onMountAutoFocus:i,onUnmountAutoFocus:a,...o}=e,[s,c]=_.useState(null),l=Er(i),u=Er(a),d=_.useRef(null),f=Nt(t,c),p=_.useRef({paused:!1,pause(){this.paused=!0},resume(){this.paused=!1}}).current;_.useEffect(()=>{if(r){let e=function(e){if(p.paused||!s)return;let t=e.target;s.contains(t)?d.current=t:$r(d.current,{select:!0})},t=function(e){if(p.paused||!s)return;let t=e.relatedTarget;t!==null&&(s.contains(t)||$r(d.current,{select:!0}))},n=function(e){if(document.activeElement===document.body)for(let t of e)t.removedNodes.length>0&&$r(s)};Hr(e,`handleFocusIn`),Hr(t,`handleFocusOut`),Hr(n,`handleMutations`),document.addEventListener(`focusin`,e),document.addEventListener(`focusout`,t);let r=new MutationObserver(n);return s&&r.observe(s,{childList:!0,subtree:!0}),()=>{document.removeEventListener(`focusin`,e),document.removeEventListener(`focusout`,t),r.disconnect()}}},[r,s,p.paused]),_.useEffect(()=>{if(s){ei.add(p);let e=document.activeElement;if(!s.contains(e)){let t=new CustomEvent(Ur,Gr);s.addEventListener(Ur,l),s.dispatchEvent(t),t.defaultPrevented||(qr(ri(Yr(s)),{select:!0}),document.activeElement===e&&$r(s))}return()=>{s.removeEventListener(Ur,l),setTimeout(()=>{let t=new CustomEvent(Wr,Gr);s.addEventListener(Wr,u),s.dispatchEvent(t),t.defaultPrevented||$r(e??document.body,{select:!0}),s.removeEventListener(Wr,u),ei.remove(p)},0)}}},[s,l,u,p]);let m=_.useCallback(e=>{if(!n&&!r||p.paused)return;let t=e.key===`Tab`&&!e.altKey&&!e.ctrlKey&&!e.metaKey,i=document.activeElement;if(t&&i){let t=e.currentTarget,[r,a]=Jr(t);r&&a?!e.shiftKey&&i===a?(e.preventDefault(),n&&$r(r,{select:!0})):e.shiftKey&&i===r&&(e.preventDefault(),n&&$r(a,{select:!0})):i===t&&e.preventDefault()}},[n,r,p.paused]);return(0,U.jsx)(W.div,{tabIndex:-1,...o,ref:f,onKeyDown:m})},`FocusScope`));function qr(e,{select:t=!1}={}){let n=document.activeElement;for(let r of e)if($r(r,{select:t}),document.activeElement!==n)return}Hr(qr,`focusFirst`);function Jr(e){let t=Yr(e);return[Xr(t,e),Xr(t.reverse(),e)]}Hr(Jr,`getTabbableEdges`);function Yr(e){let t=[],n=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT,{acceptNode:Hr(e=>{let t=e.tagName===`INPUT`&&e.type===`hidden`;return e.disabled||e.hidden||t?NodeFilter.FILTER_SKIP:e.tabIndex>=0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP},`acceptNode`)});for(;n.nextNode();)t.push(n.currentNode);return t}Hr(Yr,`getTabbableCandidates`);function Xr(e,t){let n=typeof t.checkVisibility==`function`&&t.checkVisibility({checkVisibilityCSS:!0});for(let r of e)if(!(n?!r.checkVisibility({checkVisibilityCSS:!0}):Zr(r,{upTo:t})))return r}Hr(Xr,`findVisible`);function Zr(e,{upTo:t}){if(getComputedStyle(e).visibility===`hidden`)return!0;for(;e;){if(t!==void 0&&e===t)return!1;if(getComputedStyle(e).display===`none`)return!0;e=e.parentElement}return!1}Hr(Zr,`isHidden`);function Qr(e){return e instanceof HTMLInputElement&&`select`in e}Hr(Qr,`isSelectableInput`);function $r(e,{select:t=!1}={}){if(e&&e.focus){let n=document.activeElement;e.focus({preventScroll:!0}),e!==n&&Qr(e)&&t&&e.select()}}Hr($r,`focus`);var ei=ti();function ti(){let e=[];return{add(t){let n=e[0];t!==n&&n?.pause(),e=ni(e,t),e.unshift(t)},remove(t){e=ni(e,t),e[0]?.resume()}}}Hr(ti,`createFocusScopesStack`);function ni(e,t){let n=[...e],r=n.indexOf(t);return r!==-1&&n.splice(r,1),n}Hr(ni,`arrayRemove`);function ri(e){return e.filter(e=>e.tagName!==`A`)}Hr(ri,`removeLinks`);var ii=Object.defineProperty,ai=_.forwardRef(((e,t)=>ii(e,`name`,{value:t,configurable:!0}))(function(e,t){let{container:n,...r}=e,[i,a]=_.useState(!1);jn(()=>a(!0),[]);let o=n||i&&globalThis?.document?.body;return o?Pt.createPortal((0,U.jsx)(W.div,{...r,ref:t}),o):null},`Portal`)),oi=Object.defineProperty,si=(e,t)=>oi(e,`name`,{value:t,configurable:!0}),ci=0,li=null;function ui(e){return di(),e.children}si(ui,`FocusGuards`);function di(){_.useEffect(()=>{li||={start:fi(),end:fi()};let{start:e,end:t}=li;return document.body.firstElementChild!==e&&document.body.insertAdjacentElement(`afterbegin`,e),document.body.lastElementChild!==t&&document.body.insertAdjacentElement(`beforeend`,t),ci++,()=>{ci===1&&(li?.start.remove(),li?.end.remove(),li=null),ci=Math.max(0,ci-1)}},[])}si(di,`useFocusGuards`);function fi(){let e=document.createElement(`span`);return e.setAttribute(`data-radix-focus-guard`,``),e.tabIndex=0,e.style.outline=`none`,e.style.opacity=`0`,e.style.position=`fixed`,e.style.pointerEvents=`none`,e}si(fi,`createFocusGuard`);var pi=function(){return pi=Object.assign||function(e){for(var t,n=1,r=arguments.length;n`u`)return Bi;var t=Hi(e),n=document.documentElement.clientWidth,r=window.innerWidth;return{left:t[0],top:t[1],right:t[2],gap:Math.max(0,r-n+t[2]-t[0])}},Wi=zi(),Gi=`data-scroll-locked`,Ki=function(e,t,n,r){var i=e.left,a=e.top,o=e.right,s=e.gap;return n===void 0&&(n=`margin`),` + .${vi} { + overflow: hidden ${r}; + padding-right: ${s}px ${r}; + } + body[${Gi}] { + overflow: hidden ${r}; + overscroll-behavior: contain; + ${[t&&`position: relative ${r};`,n===`margin`&&` + padding-left: ${i}px; + padding-top: ${a}px; + padding-right: ${o}px; + margin-left:0; + margin-top:0; + margin-right: ${s}px ${r}; + `,n===`padding`&&`padding-right: ${s}px ${r};`].filter(Boolean).join(``)} + } + + .${gi} { + right: ${s}px ${r}; + } + + .${_i} { + margin-right: ${s}px ${r}; + } + + .${gi} .${gi} { + right: 0 ${r}; + } + + .${_i} .${_i} { + margin-right: 0 ${r}; + } + + body[${Gi}] { + ${yi}: ${s}px; + } +`},qi=function(){var e=parseInt(document.body.getAttribute(`data-scroll-locked`)||`0`,10);return isFinite(e)?e:0},Ji=function(){_.useEffect(function(){return document.body.setAttribute(Gi,(qi()+1).toString()),function(){var e=qi()-1;e<=0?document.body.removeAttribute(Gi):document.body.setAttribute(Gi,e.toString())}},[])},Yi=function(e){var t=e.noRelative,n=e.noImportant,r=e.gapMode,i=r===void 0?`margin`:r;Ji();var a=_.useMemo(function(){return Ui(i)},[i]);return _.createElement(Wi,{styles:Ki(a,!t,i,n?``:`!important`)})},Xi=!1;if(typeof window<`u`)try{var Zi=Object.defineProperty({},"passive",{get:function(){return Xi=!0,!0}});window.addEventListener(`test`,Zi,Zi),window.removeEventListener(`test`,Zi,Zi)}catch{Xi=!1}var Qi=Xi?{passive:!1}:!1,$i=function(e){return e.tagName===`TEXTAREA`},ea=function(e,t){if(!(e instanceof Element))return!1;var n=window.getComputedStyle(e);return n[t]!==`hidden`&&!(n.overflowY===n.overflowX&&!$i(e)&&n[t]===`visible`)},ta=function(e){return ea(e,`overflowY`)},na=function(e){return ea(e,`overflowX`)},ra=function(e,t){var n=t.ownerDocument,r=t;do{if(typeof ShadowRoot<`u`&&r instanceof ShadowRoot&&(r=r.host),oa(e,r)){var i=sa(e,r);if(i[1]>i[2])return!0}r=r.parentNode}while(r&&r!==n.body);return!1},ia=function(e){return[e.scrollTop,e.scrollHeight,e.clientHeight]},aa=function(e){return[e.scrollLeft,e.scrollWidth,e.clientWidth]},oa=function(e,t){return e===`v`?ta(t):na(t)},sa=function(e,t){return e===`v`?ia(t):aa(t)},ca=function(e,t){return e===`h`&&t===`rtl`?-1:1},la=function(e,t,n,r,i){var a=ca(e,window.getComputedStyle(t).direction),o=a*r,s=n.target,c=t.contains(s),l=!1,u=o>0,d=0,f=0;do{if(!s)break;var p=sa(e,s),m=p[0],h=p[1]-p[2]-a*m;(m||h)&&oa(e,s)&&(d+=h,f+=m);var g=s.parentNode;s=g&&g.nodeType===Node.DOCUMENT_FRAGMENT_NODE?g.host:g}while(!c&&s!==document.body||c&&(t.contains(s)||t===s));return(u&&(i&&Math.abs(d)<1||!i&&o>d)||!u&&(i&&Math.abs(f)<1||!i&&-o>f))&&(l=!0),l},ua=function(e){return`changedTouches`in e?[e.changedTouches[0].clientX,e.changedTouches[0].clientY]:[0,0]},da=function(e){return[e.deltaX,e.deltaY]},fa=function(e){return e&&`current`in e?e.current:e},pa=function(e,t){return e[0]===t[0]&&e[1]===t[1]},ma=function(e){return` + .block-interactivity-${e} {pointer-events: none;} + .allow-interactivity-${e} {pointer-events: all;} +`},ha=0,ga=[];function _a(e){var t=_.useRef([]),n=_.useRef([0,0]),r=_.useRef(),i=_.useState(ha++)[0],a=_.useState(zi)[0],o=_.useRef(e);_.useEffect(function(){o.current=e},[e]),_.useEffect(function(){if(e.inert){document.body.classList.add(`block-interactivity-${i}`);var t=hi([e.lockRef.current],(e.shards||[]).map(fa),!0).filter(Boolean);return t.forEach(function(e){return e.classList.add(`allow-interactivity-${i}`)}),function(){document.body.classList.remove(`block-interactivity-${i}`),t.forEach(function(e){return e.classList.remove(`allow-interactivity-${i}`)})}}},[e.inert,e.lockRef.current,e.shards]);var s=_.useCallback(function(e,t){if(`touches`in e&&e.touches.length===2||e.type===`wheel`&&e.ctrlKey)return!o.current.allowPinchZoom;var i=ua(e),a=n.current,s=`deltaX`in e?e.deltaX:a[0]-i[0],c=`deltaY`in e?e.deltaY:a[1]-i[1],l,u=e.target,d=Math.abs(s)>Math.abs(c)?`h`:`v`;if(`touches`in e&&d===`h`&&u.type===`range`)return!1;var f=window.getSelection(),p=f&&f.anchorNode;if(p&&(p===u||p.contains(u)))return!1;var m=ra(d,u);if(!m)return!0;if(m?l=d:(l=d===`v`?`h`:`v`,m=ra(d,u)),!m)return!1;if(!r.current&&`changedTouches`in e&&(s||c)&&(r.current=l),!l)return!0;var h=r.current||l;return la(h,t,e,h===`h`?s:c,!0)},[]),c=_.useCallback(function(e){var n=e;if(!(!ga.length||ga[ga.length-1]!==a)){var r=`deltaY`in n?da(n):ua(n),i=t.current.filter(function(e){return e.name===n.type&&(e.target===n.target||n.target===e.shadowParent)&&pa(e.delta,r)})[0];if(i&&i.should){n.cancelable&&n.preventDefault();return}if(!i){var c=(o.current.shards||[]).map(fa).filter(Boolean).filter(function(e){return e.contains(n.target)});(c.length>0?s(n,c[0]):!o.current.noIsolation)&&n.cancelable&&n.preventDefault()}}},[]),l=_.useCallback(function(e,n,r,i){var a={name:e,delta:n,target:r,should:i,shadowParent:va(r)};t.current.push(a),setTimeout(function(){t.current=t.current.filter(function(e){return e!==a})},1)},[]),u=_.useCallback(function(e){n.current=ua(e),r.current=void 0},[]),d=_.useCallback(function(t){l(t.type,da(t),t.target,s(t,e.lockRef.current))},[]),f=_.useCallback(function(t){l(t.type,ua(t),t.target,s(t,e.lockRef.current))},[]);_.useEffect(function(){return ga.push(a),e.setCallbacks({onScrollCapture:d,onWheelCapture:d,onTouchMoveCapture:f}),document.addEventListener(`wheel`,c,Qi),document.addEventListener(`touchmove`,c,Qi),document.addEventListener(`touchstart`,u,Qi),function(){ga=ga.filter(function(e){return e!==a}),document.removeEventListener(`wheel`,c,Qi),document.removeEventListener(`touchmove`,c,Qi),document.removeEventListener(`touchstart`,u,Qi)}},[]);var p=e.removeScrollBar,m=e.inert;return _.createElement(_.Fragment,null,m?_.createElement(a,{styles:ma(i)}):null,p?_.createElement(Yi,{noRelative:e.noRelative,gapMode:e.gapMode}):null)}function va(e){for(var t=null;e!==null;)e instanceof ShadowRoot&&(t=e.host,e=e.host),e=e.parentNode;return t}var ya=Oi(ki,_a),ba=_.forwardRef(function(e,t){return _.createElement(ji,pi({},e,{ref:t,sideCar:ya}))});ba.classNames=ji.classNames;var xa=function(e){return typeof document>`u`?null:(Array.isArray(e)?e[0]:e).ownerDocument.body},Sa=new WeakMap,Ca=new WeakMap,wa={},Ta=0,Ea=function(e){return e&&(e.host||Ea(e.parentNode))},Da=function(e,t){return t.map(function(t){if(e.contains(t))return t;var n=Ea(t);return n&&e.contains(n)?n:(console.error(`aria-hidden`,t,`in not contained inside`,e,`. Doing nothing`),null)}).filter(function(e){return!!e})},Oa=function(e,t,n,r){var i=Da(t,Array.isArray(e)?e:[e]);wa[n]||(wa[n]=new WeakMap);var a=wa[n],o=[],s=new Set,c=new Set(i),l=function(e){!e||s.has(e)||(s.add(e),l(e.parentNode))};i.forEach(l);var u=function(e){!e||c.has(e)||Array.prototype.forEach.call(e.children,function(e){if(s.has(e))u(e);else try{var t=e.getAttribute(r),i=t!==null&&t!==`false`,c=(Sa.get(e)||0)+1,l=(a.get(e)||0)+1;Sa.set(e,c),a.set(e,l),o.push(e),c===1&&i&&Ca.set(e,!0),l===1&&e.setAttribute(n,`true`),i||e.setAttribute(r,`true`)}catch(t){console.error(`aria-hidden: cannot operate on `,e,t)}})};return u(t),s.clear(),Ta++,function(){o.forEach(function(e){var t=Sa.get(e)-1,i=a.get(e)-1;Sa.set(e,t),a.set(e,i),t||(Ca.has(e)||e.removeAttribute(r),Ca.delete(e)),i||e.removeAttribute(n)}),Ta--,Ta||(Sa=new WeakMap,Sa=new WeakMap,Ca=new WeakMap,wa={})}},ka=function(e,t,n){n===void 0&&(n=`data-aria-hidden`);var r=Array.from(Array.isArray(e)?e:[e]),i=t||xa(e);return i?(r.push.apply(r,Array.from(i.querySelectorAll(`[aria-live], script`))),Oa(r,i,n,`aria-hidden`)):function(){return null}},Aa=Object.defineProperty,ja=(e,t)=>Aa(e,`name`,{value:t,configurable:!0}),Ma=`Dialog`,[Na,Pa]=ln(Ma),[Fa,Ia]=Na(Ma),La=ja(e=>{let{__scopeDialog:t,children:n,open:r,defaultOpen:i,onOpenChange:a,modal:o=!0}=e,s=_.useRef(null),c=_.useRef(null),[l,u]=Bn({prop:r,defaultProp:i??!1,onChange:a,caller:Ma}),[d,f]=_.useState(0),[p,m]=_.useState(0);return(0,U.jsx)(Fa,{scope:t,triggerRef:s,contentRef:c,contentId:ir(),titleId:ir(),descriptionId:ir(),titlePresent:d>0,descriptionPresent:p>0,setTitleCount:f,setDescriptionCount:m,open:l,onOpenChange:u,onOpenToggle:_.useCallback(()=>u(e=>!e),[u]),modal:o,children:n})},`Dialog`),Ra=`DialogTrigger`,za=_.forwardRef(ja(function(e,t){let{__scopeDialog:n,...r}=e,i=Ia(Ra,n),a=Nt(t,i.triggerRef);return(0,U.jsx)(W.button,{type:`button`,"aria-haspopup":`dialog`,"aria-expanded":i.open,"aria-controls":i.open?i.contentId:void 0,"data-state":ao(i.open),...r,ref:a,onClick:G(e.onClick,i.onOpenToggle)})},`DialogTrigger`)),Ba=`DialogPortal`,[Va,Ha]=Na(Ba,{forceMount:void 0}),Ua=ja(e=>{let{__scopeDialog:t,forceMount:n,children:r,container:i}=e,a=Ia(Ba,t);return(0,U.jsx)(Va,{scope:t,forceMount:n,children:_.Children.map(r,e=>(0,U.jsx)(Jn,{present:n||a.open,children:(0,U.jsx)(ai,{asChild:!0,container:i,children:e})}))})},`DialogPortal`),Wa=`DialogOverlay`,Ga=_.forwardRef(ja(function(e,t){let n=Ha(Wa,e.__scopeDialog),{forceMount:r=n.forceMount,...i}=e,a=Ia(Wa,e.__scopeDialog);return a.modal?(0,U.jsx)(Jn,{present:r||a.open,children:(0,U.jsx)(qa,{...i,ref:t})}):null},`DialogOverlay`)),Ka=Lt(`DialogOverlay.RemoveScroll`),qa=_.forwardRef(ja(function(e,t){let{__scopeDialog:n,...r}=e,i=Ia(Wa,n),a=Nt(t,Fr());return(0,U.jsx)(ba,{as:Ka,allowPinchZoom:!0,shards:[i.contentRef],children:(0,U.jsx)(W.div,{"data-state":ao(i.open),...r,ref:a,style:{pointerEvents:`auto`,...r.style}})})},`DialogOverlayImpl`)),Ja=`DialogContent`,Ya=_.forwardRef(ja(function(e,t){let n=Ha(Ja,e.__scopeDialog),{forceMount:r=n.forceMount,...i}=e,a=Ia(Ja,e.__scopeDialog);return(0,U.jsx)(Jn,{present:r||a.open,children:a.modal?(0,U.jsx)(Xa,{...i,ref:t}):(0,U.jsx)(Za,{...i,ref:t})})},`DialogContent`)),Xa=_.forwardRef(ja(function(e,t){let n=Ia(Ja,e.__scopeDialog),r=_.useRef(null),i=Nt(t,n.contentRef,r);return _.useEffect(()=>{let e=r.current;if(e)return ka(e)},[]),(0,U.jsx)(Qa,{...e,ref:i,trapFocus:n.open,disableOutsidePointerEvents:n.open,onCloseAutoFocus:G(e.onCloseAutoFocus,e=>{e.preventDefault(),n.triggerRef.current?.focus()}),onPointerDownOutside:G(e.onPointerDownOutside,e=>{let t=e.detail.originalEvent,n=t.button===0&&t.ctrlKey===!0;(t.button===2||n)&&e.preventDefault()}),onFocusOutside:G(e.onFocusOutside,e=>e.preventDefault())})},`DialogContentModal`)),Za=_.forwardRef(ja(function(e,t){let n=Ia(Ja,e.__scopeDialog),r=_.useRef(!1),i=_.useRef(!1);return(0,U.jsx)(Qa,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:t=>{e.onCloseAutoFocus?.(t),t.defaultPrevented||(r.current||n.triggerRef.current?.focus(),t.preventDefault()),r.current=!1,i.current=!1},onInteractOutside:t=>{e.onInteractOutside?.(t),t.defaultPrevented||(r.current=!0,t.detail.originalEvent.type===`pointerdown`&&(i.current=!0));let a=t.target;n.triggerRef.current?.contains(a)&&t.preventDefault(),t.detail.originalEvent.type===`focusin`&&i.current&&t.preventDefault()}})},`DialogContentNonModal`)),Qa=_.forwardRef(ja(function(e,t){let{__scopeDialog:n,trapFocus:r,onOpenAutoFocus:i,onCloseAutoFocus:a,...o}=e,s=Ia(Ja,n);return di(),(0,U.jsx)(U.Fragment,{children:(0,U.jsx)(Kr,{asChild:!0,loop:!0,trapped:r,onMountAutoFocus:i,onUnmountAutoFocus:a,children:(0,U.jsx)(Pr,{role:`dialog`,id:s.contentId,"aria-describedby":s.descriptionPresent?s.descriptionId:void 0,"aria-labelledby":s.titlePresent?s.titleId:void 0,"data-state":ao(s.open),...o,ref:t,deferPointerDownOutside:!0,onDismiss:()=>s.onOpenChange(!1)})})})},`DialogContentImpl`)),$a=`DialogTitle`,eo=_.forwardRef(ja(function(e,t){let{__scopeDialog:n,...r}=e,i=Ia($a,n),{setTitleCount:a}=i;return jn(()=>(a(e=>e+1),()=>a(e=>e-1)),[a]),(0,U.jsx)(W.h2,{id:i.titleId,...r,ref:t})},`DialogTitle`)),to=`DialogDescription`,no=_.forwardRef(ja(function(e,t){let{__scopeDialog:n,...r}=e,i=Ia(to,n),{setDescriptionCount:a}=i;return jn(()=>(a(e=>e+1),()=>a(e=>e-1)),[a]),(0,U.jsx)(W.p,{id:i.descriptionId,...r,ref:t})},`DialogDescription`)),ro=`DialogClose`,io=_.forwardRef(ja(function(e,t){let{__scopeDialog:n,...r}=e,i=Ia(ro,n);return(0,U.jsx)(W.button,{type:`button`,...r,ref:t,onClick:G(e.onClick,()=>i.onOpenChange(!1))})},`DialogClose`));function ao(e){return e?`open`:`closed`}ja(ao,`getState`);var q=Object.defineProperty,J=(e,t)=>q(e,`name`,{value:t,configurable:!0}),[oo,so]=ln(`AlertDialog`,[Pa]),co=Pa(),lo=J(e=>{let{__scopeAlertDialog:t,...n}=e,r=co(t);return(0,U.jsx)(La,{...r,...n,modal:!0})},`AlertDialog`),uo=_.forwardRef(J(function(e,t){let{__scopeAlertDialog:n,...r}=e,i=co(n);return(0,U.jsx)(za,{...i,...r,ref:t})},`AlertDialogTrigger`)),fo=J(e=>{let{__scopeAlertDialog:t,...n}=e,r=co(t);return(0,U.jsx)(Ua,{...r,...n})},`AlertDialogPortal`),po=_.forwardRef(J(function(e,t){let{__scopeAlertDialog:n,...r}=e,i=co(n);return(0,U.jsx)(Ga,{...i,...r,ref:t})},`AlertDialogOverlay`)),[mo,ho]=oo(`AlertDialogContent`),go=_.forwardRef(J(function(e,t){let{__scopeAlertDialog:n,children:r,...i}=e,a=co(n),o=Nt(t,_.useRef(null)),s=_.useRef(null);return(0,U.jsx)(mo,{scope:n,cancelRef:s,children:(0,U.jsx)(Ya,{role:`alertdialog`,...a,...i,ref:o,onOpenAutoFocus:G(i.onOpenAutoFocus,e=>{e.preventDefault(),s.current?.focus({preventScroll:!0})}),onPointerDownOutside:e=>e.preventDefault(),onInteractOutside:e=>e.preventDefault(),children:r})})},`AlertDialogContent`)),_o=_.forwardRef(J(function(e,t){let{__scopeAlertDialog:n,...r}=e,i=co(n);return(0,U.jsx)(eo,{...i,...r,ref:t})},`AlertDialogTitle`)),vo=_.forwardRef(J(function(e,t){let{__scopeAlertDialog:n,...r}=e,i=co(n);return(0,U.jsx)(no,{...i,...r,ref:t})},`AlertDialogDescription`)),yo=_.forwardRef(J(function(e,t){let{__scopeAlertDialog:n,...r}=e,i=co(n);return(0,U.jsx)(io,{...i,...r,ref:t})},`AlertDialogAction`)),bo=`AlertDialogCancel`,xo=_.forwardRef(J(function(e,t){let{__scopeAlertDialog:n,...r}=e,{cancelRef:i}=ho(bo,n),a=co(n),o=Nt(t,i);return(0,U.jsx)(io,{...a,...r,ref:o})},`AlertDialogCancel`)),So=lo,Co=uo,wo=fo,To=po,Eo=go,Do=yo,Oo=xo,ko=_o,Ao=vo,jo=Object.defineProperty,Mo=(e,t)=>jo(e,`name`,{value:t,configurable:!0});function No(e){let[t,n]=_.useState(void 0);return jn(()=>{if(e){n({width:e.offsetWidth,height:e.offsetHeight});let t=new ResizeObserver(t=>{if(!Array.isArray(t)||!t.length)return;let r=t[0],i,a;if(`borderBoxSize`in r){let e=r.borderBoxSize,t=Array.isArray(e)?e[0]:e;i=t.inlineSize,a=t.blockSize}else i=e.offsetWidth,a=e.offsetHeight;n({width:i,height:a})});return t.observe(e,{box:`border-box`}),()=>t.unobserve(e)}n(void 0)},[e]),t}Mo(No,`useSize`);var Po=Object.defineProperty,Fo=(e,t)=>Po(e,`name`,{value:t,configurable:!0}),Io=`Checkbox`,[Lo,Ro]=ln(Io),[zo,Bo]=Lo(Io);function Vo(e){let{__scopeCheckbox:t,checked:n,children:r,defaultChecked:i,disabled:a,form:o,name:s,onCheckedChange:c,required:l,value:u=`on`,internal_do_not_use_render:d}=e,[f,p]=Bn({prop:n,defaultProp:i??!1,onChange:c,caller:Io}),[m,h]=_.useState(null),[g,v]=_.useState(null),y=_.useRef(!1),[b,x]=_.useReducer(e=>e+1,0),S=!m||!!o||!!m.closest(`form`),C={checked:f,disabled:a,setChecked:p,control:m,setControl:h,name:s,form:o,value:u,hasConsumerStoppedPropagationRef:y,userInteractionCount:b,onUserInteraction:x,required:l,defaultChecked:!Xo(i)&&i,isFormControl:S,bubbleInput:g,setBubbleInput:v};return(0,U.jsx)(zo,{scope:t,...C,children:Yo(d)?d(C):r})}Fo(Vo,`CheckboxProvider`);var Ho=`CheckboxTrigger`,Uo=_.forwardRef(Fo(function({__scopeCheckbox:e,onKeyDown:t,onClick:n,...r},i){let{control:a,value:o,disabled:s,checked:c,required:l,setControl:u,setChecked:d,hasConsumerStoppedPropagationRef:f,onUserInteraction:p,isFormControl:m,bubbleInput:h}=Bo(Ho,e),g=Nt(i,u),v=_.useRef(c);return _.useEffect(()=>{let e=a?.form;if(e){let t=Fo(()=>d(v.current),`reset`);return e.addEventListener(`reset`,t),()=>e.removeEventListener(`reset`,t)}},[a,d]),(0,U.jsx)(W.button,{type:`button`,role:`checkbox`,"aria-checked":Xo(c)?`mixed`:c,"aria-required":l,"data-state":Zo(c),"data-disabled":s?``:void 0,disabled:s,value:o,...r,ref:g,onKeyDown:G(t,e=>{e.key===`Enter`&&e.preventDefault()}),onClick:G(n,e=>{p(),d(e=>Xo(e)?!0:!e),h&&m&&(f.current=e.isPropagationStopped(),f.current||e.stopPropagation())})})},`CheckboxTrigger`)),Wo=_.forwardRef(Fo(function(e,t){let{__scopeCheckbox:n,name:r,checked:i,defaultChecked:a,required:o,disabled:s,value:c,onCheckedChange:l,form:u,...d}=e;return(0,U.jsx)(Vo,{__scopeCheckbox:n,checked:i,defaultChecked:a,disabled:s,required:o,onCheckedChange:l,name:r,form:u,value:c,internal_do_not_use_render:({isFormControl:e})=>(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(Uo,{...d,ref:t,__scopeCheckbox:n}),e&&(0,U.jsx)(Jo,{__scopeCheckbox:n})]})})},`Checkbox`)),Go=`CheckboxIndicator`,Ko=_.forwardRef(Fo(function(e,t){let{__scopeCheckbox:n,forceMount:r,...i}=e,a=Bo(Go,n);return(0,U.jsx)(Jn,{present:r||Xo(a.checked)||a.checked===!0,children:(0,U.jsx)(W.span,{"data-state":Zo(a.checked),"data-disabled":a.disabled?``:void 0,...i,ref:t,style:{pointerEvents:`none`,...e.style}})})},`CheckboxIndicator`)),qo=`CheckboxBubbleInput`,Jo=_.forwardRef(Fo(function({__scopeCheckbox:e,onClick:t,...n},r){let{control:i,hasConsumerStoppedPropagationRef:a,userInteractionCount:o,checked:s,defaultChecked:c,required:l,disabled:u,name:d,value:f,form:p,bubbleInput:m,setBubbleInput:h}=Bo(qo,e),g=Nt(r,h),v=No(i),y=_.useRef(!1),b=_.useRef(s),x=_.useRef(o);_.useEffect(()=>{let e=m;if(!e)return;let t=window.HTMLInputElement.prototype,n=Object.getOwnPropertyDescriptor(t,`checked`).set,r=o!==x.current;x.current=o;let i=b.current!==s;b.current=s;let c=!(r&&a.current);if(i&&n){y.current=!r;let t=new Event(`click`,{bubbles:c});e.indeterminate=Xo(s),n.call(e,!Xo(s)&&s),e.dispatchEvent(t),y.current=!1}},[m,s,a,o]);let S=_.useRef(!Xo(s)&&s);return(0,U.jsx)(W.input,{type:`checkbox`,"aria-hidden":!0,defaultChecked:c??S.current,required:l,disabled:u,name:d,value:f,form:p,...n,tabIndex:-1,ref:g,onClick:G(t,e=>{y.current&&e.stopPropagation()}),style:{...n.style,...v,position:`absolute`,pointerEvents:`none`,opacity:0,margin:0,transform:`translateX(-100%)`}})},`CheckboxBubbleInput`));function Yo(e){return typeof e==`function`}Fo(Yo,`isFunction`);function Xo(e){return e===`indeterminate`}Fo(Xo,`isIndeterminate`);function Zo(e){return Xo(e)?`indeterminate`:e?`checked`:`unchecked`}Fo(Zo,`getState`);var Qo=[`top`,`right`,`bottom`,`left`],$o=Math.min,es=Math.max,ts=Math.round,ns=Math.floor,rs=e=>({x:e,y:e}),is={left:`right`,right:`left`,bottom:`top`,top:`bottom`};function as(e,t,n){return es(e,$o(t,n))}function os(e,t){return typeof e==`function`?e(t):e}function ss(e){return e.split(`-`)[0]}function cs(e){return e.split(`-`)[1]}function ls(e){return e===`x`?`y`:`x`}function us(e){return e===`y`?`height`:`width`}function ds(e){let t=e[0];return t===`t`||t===`b`?`y`:`x`}function fs(e){return ls(ds(e))}function ps(e,t,n){n===void 0&&(n=!1);let r=cs(e),i=fs(e),a=us(i),o=i===`x`?r===(n?`end`:`start`)?`right`:`left`:r===`start`?`bottom`:`top`;return t.reference[a]>t.floating[a]&&(o=Ss(o)),[o,Ss(o)]}function ms(e){let t=Ss(e);return[hs(e),t,hs(t)]}function hs(e){return e.includes(`start`)?e.replace(`start`,`end`):e.replace(`end`,`start`)}var gs=[`left`,`right`],_s=[`right`,`left`],vs=[`top`,`bottom`],ys=[`bottom`,`top`];function bs(e,t,n){switch(e){case`top`:case`bottom`:return n?t?_s:gs:t?gs:_s;case`left`:case`right`:return t?vs:ys;default:return[]}}function xs(e,t,n,r){let i=cs(e),a=bs(ss(e),n===`start`,r);return i&&(a=a.map(e=>e+`-`+i),t&&(a=a.concat(a.map(hs)))),a}function Ss(e){let t=ss(e);return is[t]+e.slice(t.length)}function Cs(e){return{top:e.top??0,right:e.right??0,bottom:e.bottom??0,left:e.left??0}}function ws(e){return typeof e==`number`?{top:e,right:e,bottom:e,left:e}:Cs(e)}function Ts(e){let{x:t,y:n,width:r,height:i}=e;return{width:r,height:i,top:n,left:t,right:t+r,bottom:n+i,x:t,y:n}}function Es(e,t,n){let{reference:r,floating:i}=e,a=ds(t),o=fs(t),s=us(o),c=ss(t),l=a===`y`,u=r.x+r.width/2-i.width/2,d=r.y+r.height/2-i.height/2,f=r[s]/2-i[s]/2,p;switch(c){case`top`:p={x:u,y:r.y-i.height};break;case`bottom`:p={x:u,y:r.y+r.height};break;case`right`:p={x:r.x+r.width,y:d};break;case`left`:p={x:r.x-i.width,y:d};break;default:p={x:r.x,y:r.y}}let m=cs(t);return m&&(p[o]+=f*(m===`end`?1:-1)*(n&&l?-1:1)),p}async function Ds(e,t){t===void 0&&(t={});let{x:n,y:r,platform:i,rects:a,elements:o,strategy:s}=e,{boundary:c=`clippingAncestors`,rootBoundary:l=`viewport`,elementContext:u=`floating`,altBoundary:d=!1,padding:f=0}=os(t,e),p=ws(f),m=o[d?u===`floating`?`reference`:`floating`:u],h=Ts(await i.getClippingRect({element:await(i.isElement==null?void 0:i.isElement(m))??!0?m:m.contextElement||await(i.getDocumentElement==null?void 0:i.getDocumentElement(o.floating)),boundary:c,rootBoundary:l,strategy:s})),g=u===`floating`?{x:n,y:r,width:a.floating.width,height:a.floating.height}:a.reference,_=await(i.getOffsetParent==null?void 0:i.getOffsetParent(o.floating)),v=await(i.isElement==null?void 0:i.isElement(_))&&await(i.getScale==null?void 0:i.getScale(_))||{x:1,y:1},y=Ts(i.convertOffsetParentRelativeRectToViewportRelativeRect?await i.convertOffsetParentRelativeRectToViewportRelativeRect({elements:o,rect:g,offsetParent:_,strategy:s}):g);return{top:(h.top-y.top+p.top)/v.y,bottom:(y.bottom-h.bottom+p.bottom)/v.y,left:(h.left-y.left+p.left)/v.x,right:(y.right-h.right+p.right)/v.x}}var Os=50,ks=async(e,t,n)=>{let{placement:r=`bottom`,strategy:i=`absolute`,middleware:a=[],platform:o}=n,s=o.detectOverflow?o:{...o,detectOverflow:Ds},c=await(o.isRTL==null?void 0:o.isRTL(t)),l=await o.getElementRects({reference:e,floating:t,strategy:i}),{x:u,y:d}=Es(l,r,c),f=r,p=0,m={};for(let n=0;n({name:`arrow`,options:e,async fn(t){let{x:n,y:r,placement:i,rects:a,platform:o,elements:s,middlewareData:c}=t,{element:l,padding:u=0}=os(e,t)||{};if(l==null)return{};let d=ws(u),f={x:n,y:r},p=fs(i),m=us(p),h=await o.getDimensions(l),g=p===`y`,_=g?`top`:`left`,v=g?`bottom`:`right`,y=g?`clientHeight`:`clientWidth`,b=a.reference[m]+a.reference[p]-f[p]-a.floating[m],x=f[p]-a.reference[p],S=await(o.getOffsetParent==null?void 0:o.getOffsetParent(l)),C=S?S[y]:0;(!C||!await(o.isElement==null?void 0:o.isElement(S)))&&(C=s.floating[y]||a.floating[m]);let w=b/2-x/2,T=C/2-h[m]/2-1,E=$o(d[_],T),D=$o(d[v],T),O=C-h[m]-D,k=C/2-h[m]/2+w,ee=as(E,k,O),A=!c.arrow&&cs(i)!=null&&k!==ee&&a.reference[m]/2-(ke<=0)){let e=(i.flip?.index||0)+1,t=S[e];if(t&&(u!==`alignment`||_===ds(t)||T.every(e=>ds(e.placement)!==_||e.overflows[0]>0)))return{data:{index:e,overflows:T},reset:{placement:t}};let n=T.filter(e=>e.overflows[0]<=0).sort((e,t)=>e.overflows[1]-t.overflows[1])[0]?.placement;if(!n)switch(f){case`bestFit`:{let e=T.filter(e=>{if(x){let t=ds(e.placement);return t===_||t===`y`}return!0}).map(e=>[e.placement,e.overflows.filter(e=>e>0).reduce((e,t)=>e+t,0)]).sort((e,t)=>e[1]-t[1])[0]?.[0];e&&(n=e);break}case`initialPlacement`:n=o}if(r!==n)return{reset:{placement:n}}}return{}}}};function Ms(e,t){return{top:e.top-t.height,right:e.right-t.width,bottom:e.bottom-t.height,left:e.left-t.width}}function Ns(e){return Qo.some(t=>e[t]>=0)}var Ps=function(e){return e===void 0&&(e={}),{name:`hide`,options:e,async fn(t){let{rects:n,platform:r}=t,{strategy:i=`referenceHidden`,...a}=os(e,t);switch(i){case`referenceHidden`:{let e=Ms(await r.detectOverflow(t,{...a,elementContext:`reference`}),n.reference);return{data:{referenceHiddenOffsets:e,referenceHidden:Ns(e)}}}case`escaped`:{let e=Ms(await r.detectOverflow(t,{...a,altBoundary:!0}),n.floating);return{data:{escapedOffsets:e,escaped:Ns(e)}}}default:return{}}}}},Fs=new Set([`left`,`top`]);async function Is(e,t){let{placement:n,platform:r,elements:i}=e,a=await(r.isRTL==null?void 0:r.isRTL(i.floating)),o=ss(n),s=cs(n),c=ds(n)===`y`,l=Fs.has(o)?-1:1,u=a&&c?-1:1,d=os(t,e),{mainAxis:f,crossAxis:p,alignmentAxis:m}=typeof d==`number`?{mainAxis:d,crossAxis:0,alignmentAxis:null}:{mainAxis:d.mainAxis||0,crossAxis:d.crossAxis||0,alignmentAxis:d.alignmentAxis};return s&&typeof m==`number`&&(p=s===`end`?m*-1:m),c?{x:p*u,y:f*l}:{x:f*l,y:p*u}}var Ls=function(e){return e===void 0&&(e=0),{name:`offset`,options:e,async fn(t){var n;let{x:r,y:i,placement:a,middlewareData:o}=t,s=await Is(t,e);return a===o.offset?.placement&&(n=o.arrow)!=null&&n.alignmentOffset?{}:{x:r+s.x,y:i+s.y,data:{...s,placement:a}}}}},Rs=function(e){return e===void 0&&(e={}),{name:`shift`,options:e,async fn(t){let{x:n,y:r,placement:i,platform:a}=t,{mainAxis:o=!0,crossAxis:s=!1,limiter:c={fn:e=>{let{x:t,y:n}=e;return{x:t,y:n}}},...l}=os(e,t),u={x:n,y:r},d=await a.detectOverflow(t,l),f=ds(i),p=ls(f),m=u[p],h=u[f],g=(e,t)=>as(t+d[e===`y`?`top`:`left`],t,t-d[e===`y`?`bottom`:`right`]);o&&(m=g(p,m)),s&&(h=g(f,h));let _=c.fn({...t,[p]:m,[f]:h});return{..._,data:{x:_.x-n,y:_.y-r,enabled:{[p]:o,[f]:s}}}}}},zs=function(e){return e===void 0&&(e={}),{options:e,fn(t){let{x:n,y:r,placement:i,rects:a,middlewareData:o}=t,{offset:s=0,mainAxis:c=!0,crossAxis:l=!0}=os(e,t),u={x:n,y:r},d=ds(i),f=ls(d),p=u[f],m=u[d],h=os(s,t),g=typeof h==`number`?{mainAxis:h,crossAxis:0}:{mainAxis:h.mainAxis??0,crossAxis:h.crossAxis??0};if(c){let e=f===`y`?`height`:`width`,t=a.reference[f]-a.floating[e]+g.mainAxis,n=a.reference[f]+a.reference[e]-g.mainAxis;pn&&(p=n)}if(l){let e=f===`y`?`width`:`height`,t=Fs.has(ss(i)),n=a.reference[d]-a.floating[e]+(t&&o.offset?.[d]||0)+(t?0:g.crossAxis),r=a.reference[d]+a.reference[e]+(t?0:o.offset?.[d]||0)-(t?g.crossAxis:0);mr&&(m=r)}return{[f]:p,[d]:m}}}},Bs=function(e){return e===void 0&&(e={}),{name:`size`,options:e,async fn(t){let{placement:n,rects:r,platform:i,elements:a}=t,{apply:o=()=>{},...s}=os(e,t),c=await i.detectOverflow(t,s),l=ss(n),u=cs(n),d=ds(n)===`y`,{width:f,height:p}=r.floating,m,h;l===`top`||l===`bottom`?(m=l,h=u===(await(i.isRTL==null?void 0:i.isRTL(a.floating))?`start`:`end`)?`left`:`right`):(h=l,m=u===`end`?`top`:`bottom`);let g=p-c.top-c.bottom,_=f-c.left-c.right,v=$o(p-c[m],g),y=$o(f-c[h],_),b=t.middlewareData.shift,x=!b,S=v,C=y;b!=null&&b.enabled.x&&(C=_),b!=null&&b.enabled.y&&(S=g),x&&!u&&(d?C=f-2*es(c.left,c.right):S=p-2*es(c.top,c.bottom)),await o({...t,availableWidth:C,availableHeight:S});let w=await i.getDimensions(a.floating);return f!==w.width||p!==w.height?{reset:{rects:!0}}:{}}}};function Vs(){return typeof window<`u`}function Hs(e){return Gs(e)?(e.nodeName||``).toLowerCase():`#document`}function Us(e){var t;return(e==null||(t=e.ownerDocument)==null?void 0:t.defaultView)||window}function Ws(e){return((Gs(e)?e.ownerDocument:e.document)||window.document)?.documentElement}function Gs(e){return Vs()?e instanceof Node||e instanceof Us(e).Node:!1}function Ks(e){return Vs()?e instanceof Element||e instanceof Us(e).Element:!1}function qs(e){return Vs()?e instanceof HTMLElement||e instanceof Us(e).HTMLElement:!1}function Js(e){return!Vs()||typeof ShadowRoot>`u`?!1:e instanceof ShadowRoot||e instanceof Us(e).ShadowRoot}function Ys(e){let{overflow:t,overflowX:n,overflowY:r,display:i}=oc(e);return/auto|scroll|overlay|hidden|clip/.test(t+r+n)&&i!==`inline`&&i!==`contents`}function Xs(e){return/^(table|td|th)$/.test(Hs(e))}function Zs(e){try{if(e.matches(`:popover-open`))return!0}catch{}try{return e.matches(`:modal`)}catch{return!1}}var Qs=/transform|translate|scale|rotate|perspective|filter/,$s=/paint|layout|strict|content/,ec=e=>!!e&&e!==`none`,tc;function nc(e){let t=Ks(e)?oc(e):e;return ec(t.transform)||ec(t.translate)||ec(t.scale)||ec(t.rotate)||ec(t.perspective)||!ic()&&(ec(t.backdropFilter)||ec(t.filter))||Qs.test(t.willChange||``)||$s.test(t.contain||``)}function rc(e){let t=cc(e);for(;qs(t)&&!ac(t);){if(nc(t))return t;if(Zs(t))return null;t=cc(t)}return null}function ic(){return tc??=typeof CSS<`u`&&CSS.supports&&CSS.supports(`-webkit-backdrop-filter`,`none`),tc}function ac(e){return/^(html|body|#document)$/.test(Hs(e))}function oc(e){return Us(e).getComputedStyle(e)}function sc(e){return Ks(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function cc(e){if(Hs(e)===`html`)return e;let t=e.assignedSlot||e.parentNode||Js(e)&&e.host||Ws(e);return Js(t)?t.host:t}function lc(e){let t=cc(e);return ac(t)?(e.ownerDocument||e).body:qs(t)&&Ys(t)?t:lc(t)}function uc(e,t,n){t===void 0&&(t=[]),n===void 0&&(n=!0);let r=lc(e),i=r===e.ownerDocument?.body,a=Us(r);if(i){let e=dc(a);return t.concat(a,a.visualViewport||[],Ys(r)?r:[],e&&n?uc(e):[])}return t.concat(r,uc(r,[],n))}function dc(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}function fc(e){let t=oc(e),n=parseFloat(t.width)||0,r=parseFloat(t.height)||0,i=qs(e),a=i?e.offsetWidth:n,o=i?e.offsetHeight:r,s=ts(n)!==a||ts(r)!==o;return s&&(n=a,r=o),{width:n,height:r,$:s}}function pc(e){return Ks(e)?e:e.contextElement}function mc(e){let t=pc(e);if(!qs(t))return rs(1);let n=t.getBoundingClientRect(),{width:r,height:i,$:a}=fc(t),o=(a?ts(n.width):n.width)/r,s=(a?ts(n.height):n.height)/i;return(!o||!Number.isFinite(o))&&(o=1),(!s||!Number.isFinite(s))&&(s=1),{x:o,y:s}}var hc=rs(0);function gc(e){let t=Us(e);return!ic()||!t.visualViewport?hc:{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}}function _c(e,t,n){return t===void 0&&(t=!1),!!n&&t&&n===Us(e)}function vc(e,t,n,r){t===void 0&&(t=!1),n===void 0&&(n=!1);let i=e.getBoundingClientRect(),a=pc(e),o=rs(1);t&&(r?Ks(r)&&(o=mc(r)):o=mc(e));let s=_c(a,n,r)?gc(a):rs(0),c=(i.left+s.x)/o.x,l=(i.top+s.y)/o.y,u=i.width/o.x,d=i.height/o.y;if(a&&r){let e=Us(a),t=Ks(r)?Us(r):r,n=e,i=dc(n);for(;i&&t!==n;){let e=mc(i),t=i.getBoundingClientRect(),r=oc(i),a=t.left+(i.clientLeft+parseFloat(r.paddingLeft))*e.x,o=t.top+(i.clientTop+parseFloat(r.paddingTop))*e.y;c*=e.x,l*=e.y,u*=e.x,d*=e.y,c+=a,l+=o,n=Us(i),i=dc(n)}}return Ts({width:u,height:d,x:c,y:l})}function yc(e,t){let n=sc(e).scrollLeft;return t?t.left+n:vc(Ws(e)).left+n}function bc(e,t){let n=e.getBoundingClientRect();return{x:n.left+t.scrollLeft-yc(e,n),y:n.top+t.scrollTop}}function xc(e){let{elements:t,rect:n,offsetParent:r,strategy:i}=e,a=i===`fixed`,o=Ws(r),s=t?Zs(t.floating):!1;if(r===o||s&&a)return n;let c={scrollLeft:0,scrollTop:0},l=rs(1),u=rs(0),d=qs(r);if((d||!a)&&((Hs(r)!==`body`||Ys(o))&&(c=sc(r)),d)){let e=vc(r);l=mc(r),u.x=e.x+r.clientLeft,u.y=e.y+r.clientTop}let f=o&&!d&&!a?bc(o,c):rs(0);return{width:n.width*l.x,height:n.height*l.y,x:n.x*l.x-c.scrollLeft*l.x+u.x+f.x,y:n.y*l.y-c.scrollTop*l.y+u.y+f.y}}function Sc(e){return e.getClientRects?Array.from(e.getClientRects()):[]}function Cc(e){let t=sc(e),n=e.ownerDocument.body,r=es(e.scrollWidth,e.clientWidth,n.scrollWidth,n.clientWidth),i=es(e.scrollHeight,e.clientHeight,n.scrollHeight,n.clientHeight),a=-t.scrollLeft+yc(e),o=-t.scrollTop;return oc(n).direction===`rtl`&&(a+=es(e.clientWidth,n.clientWidth)-r),{width:r,height:i,x:a,y:o}}var wc=25;function Tc(e,t,n){n===void 0&&(n=`viewport`);let r=n===`layoutViewport`,i=Us(e),a=Ws(e),o=i.visualViewport,s=a.clientWidth,c=a.clientHeight,l=0,u=0;if(o){let e=!ic()||t===`fixed`;r?e||(l=-o.offsetLeft,u=-o.offsetTop):(s=o.width,c=o.height,e&&(l=o.offsetLeft,u=o.offsetTop))}if(yc(a)<=0){let e=a.ownerDocument,t=e.body,n=getComputedStyle(t),r=e.compatMode===`CSS1Compat`&&parseFloat(n.marginLeft)+parseFloat(n.marginRight)||0,i=Math.abs(a.clientWidth-t.clientWidth-r),o=getComputedStyle(a).scrollbarGutter===`stable both-edges`?i/2:i;o<=wc&&(s-=o)}return{width:s,height:c,x:l,y:u}}function Ec(e,t){let n=vc(e,!0,t===`fixed`),r=n.top+e.clientTop,i=n.left+e.clientLeft,a=mc(e);return{width:e.clientWidth*a.x,height:e.clientHeight*a.y,x:i*a.x,y:r*a.y}}function Dc(e,t,n){let r;if(t===`viewport`||t===`layoutViewport`)r=Tc(e,n,t);else if(t===`document`)r=Cc(Ws(e));else if(Ks(t))r=Ec(t,n);else{let n=gc(e);r={x:t.x-n.x,y:t.y-n.y,width:t.width,height:t.height}}return Ts(r)}function Oc(e,t){let n=t.get(e);if(n)return n;let r=uc(e,[],!1).filter(e=>Ks(e)&&Hs(e)!==`body`),i=null,a=oc(e).position===`fixed`,o=a?cc(e):e;for(;Ks(o)&&!ac(o);){let e=oc(o),t=nc(o),n=i?i.position:a?`fixed`:``;!t&&(n===`fixed`||n===`absolute`&&e.position===`static`)?r=r.filter(e=>e!==o):i=e,o=cc(o)}return t.set(e,r),r}function kc(e){let{element:t,boundary:n,rootBoundary:r,strategy:i}=e,a=[...n===`clippingAncestors`?Zs(t)?[]:Oc(t,this._c):[].concat(n),r],o=Dc(t,a[0],i),s=o.top,c=o.right,l=o.bottom,u=o.left;for(let e=1;e{s(!1,1e-7)},1e3)}y=!1}try{r=new IntersectionObserver(b,{...v,root:a.ownerDocument})}catch{r=new IntersectionObserver(b,v)}r.observe(e)}let c=Us(e),l=()=>s(n);return c.addEventListener(`resize`,l),s(!0),()=>{c.removeEventListener(`resize`,l),o()}}function Bc(e,t,n,r){r===void 0&&(r={});let{ancestorScroll:i=!0,ancestorResize:a=!0,elementResize:o=typeof ResizeObserver==`function`,layoutShift:s=typeof IntersectionObserver==`function`,animationFrame:c=!1}=r,l=pc(e),u=i||a?[...l?uc(l):[],...t?uc(t):[]]:[];u.forEach(e=>{i&&e.addEventListener(`scroll`,n),a&&e.addEventListener(`resize`,n)});let d=l&&s?zc(l,n,a):null,f=-1,p=null;o&&(p=new ResizeObserver(e=>{let[r]=e;r&&r.target===l&&p&&t&&(p.unobserve(t),cancelAnimationFrame(f),f=requestAnimationFrame(()=>{var e;(e=p)==null||e.observe(t)})),n()}),l&&!c&&p.observe(l),t&&p.observe(t));let m,h=c?vc(e):null;c&&g();function g(){let t=vc(e);h&&!Rc(h,t)&&n(),h=t,m=requestAnimationFrame(g)}return n(),()=>{var e;u.forEach(e=>{i&&e.removeEventListener(`scroll`,n),a&&e.removeEventListener(`resize`,n)}),d?.(),(e=p)==null||e.disconnect(),p=null,c&&cancelAnimationFrame(m)}}var Vc=Ls,Hc=Rs,Uc=js,Wc=Bs,Gc=Ps,Kc=As,qc=zs,Jc=(e,t,n)=>{let r=new Map,i=n??{},a={...Lc,...i.platform,_c:r};return ks(e,t,{...i,platform:a})},Yc=typeof document<`u`?_.useLayoutEffect:function(){};function Xc(e,t){if(e===t)return!0;if(typeof e!=typeof t)return!1;if(typeof e==`function`&&e.toString()===t.toString())return!0;let n,r,i;if(e&&t&&typeof e==`object`){if(Array.isArray(e)){if(n=e.length,n!==t.length)return!1;for(r=n;r--!==0;)if(!Xc(e[r],t[r]))return!1;return!0}if(i=Object.keys(e),n=i.length,n!==Object.keys(t).length)return!1;for(r=n;r--!==0;)if(!{}.hasOwnProperty.call(t,i[r]))return!1;for(r=n;r--!==0;){let n=i[r];if(!(n===`_owner`&&e.$$typeof)&&!Xc(e[n],t[n]))return!1}return!0}return e!==e&&t!==t}function Zc(e){return typeof window>`u`?1:(e.ownerDocument.defaultView||window).devicePixelRatio||1}function Qc(e,t){let n=Zc(e);return Math.round(t*n)/n}function $c(e){let t=_.useRef(e);return Yc(()=>{t.current=e}),t}function el(e){e===void 0&&(e={});let{placement:t=`bottom`,strategy:n=`absolute`,middleware:r=[],platform:i,elements:{reference:a,floating:o}={},transform:s=!0,whileElementsMounted:c,open:l}=e,[u,d]=_.useState({x:0,y:0,strategy:n,placement:t,middlewareData:{},isPositioned:!1}),[f,p]=_.useState(r);Xc(f,r)||p(r);let[m,h]=_.useState(null),[g,v]=_.useState(null),y=_.useCallback(e=>{e!==C.current&&(C.current=e,h(e))},[]),b=_.useCallback(e=>{e!==w.current&&(w.current=e,v(e))},[]),x=a||m,S=o||g,C=_.useRef(null),w=_.useRef(null),T=_.useRef(u),E=c!=null,D=$c(c),O=$c(i),k=$c(l),ee=_.useCallback(()=>{if(!C.current||!w.current)return;let e={placement:t,strategy:n,middleware:f};O.current&&(e.platform=O.current),Jc(C.current,w.current,e).then(e=>{let t={...e,isPositioned:k.current!==!1};A.current&&!Xc(T.current,t)&&(T.current=t,Pt.flushSync(()=>{d(t)}))})},[f,t,n,O,k]);Yc(()=>{l===!1&&T.current.isPositioned&&(T.current.isPositioned=!1,d(e=>({...e,isPositioned:!1})))},[l]);let A=_.useRef(!1);Yc(()=>(A.current=!0,()=>{A.current=!1}),[]),Yc(()=>{if(x&&(C.current=x),S&&(w.current=S),x&&S){if(D.current)return D.current(x,S,ee);ee()}},[x,S,ee,D,E]);let j=_.useMemo(()=>({reference:C,floating:w,setReference:y,setFloating:b}),[y,b]),M=_.useMemo(()=>({reference:x,floating:S}),[x,S]),N=_.useMemo(()=>{let e={position:n,left:0,top:0};if(!M.floating)return e;let t=Qc(M.floating,u.x),r=Qc(M.floating,u.y);return s?{...e,transform:`translate(`+t+`px, `+r+`px)`,...Zc(M.floating)>=1.5&&{willChange:`transform`}}:{position:n,left:t,top:r}},[n,s,M.floating,u.x,u.y]);return _.useMemo(()=>({...u,update:ee,refs:j,elements:M,floatingStyles:N}),[u,ee,j,M,N])}var tl=e=>{function t(e){return{}.hasOwnProperty.call(e,`current`)}return{name:`arrow`,options:e,fn(n){let{element:r,padding:i}=typeof e==`function`?e(n):e;return r&&t(r)?r.current==null?{}:Kc({element:r.current,padding:i}).fn(n):r?Kc({element:r,padding:i}).fn(n):{}}}},nl=(e,t)=>{let n=Vc(e);return{name:n.name,fn:n.fn,options:[e,t]}},rl=(e,t)=>{let n=Hc(e);return{name:n.name,fn:n.fn,options:[e,t]}},il=(e,t)=>({fn:qc(e).fn,options:[e,t]}),al=(e,t)=>{let n=Uc(e);return{name:n.name,fn:n.fn,options:[e,t]}},ol=(e,t)=>{let n=Wc(e);return{name:n.name,fn:n.fn,options:[e,t]}},sl=(e,t)=>{let n=Gc(e);return{name:n.name,fn:n.fn,options:[e,t]}},cl=(e,t)=>{let n=tl(e);return{name:n.name,fn:n.fn,options:[e,t]}},ll=Object.defineProperty,ul=_.forwardRef(((e,t)=>ll(e,`name`,{value:t,configurable:!0}))(function(e,t){let{children:n,width:r=10,height:i=5,...a}=e;return(0,U.jsx)(W.svg,{...a,ref:t,width:r,height:i,viewBox:`0 0 30 10`,preserveAspectRatio:`none`,children:e.asChild?n:(0,U.jsx)(`polygon`,{points:`0,0 30,0 15,10`})})},`Arrow`)),dl=Object.defineProperty,fl=(e,t)=>dl(e,`name`,{value:t,configurable:!0}),pl=`Popper`,[ml,hl]=ln(pl),[gl,_l]=ml(pl),vl=fl(e=>{let{__scopePopper:t,children:n}=e,[r,i]=_.useState(null),[a,o]=_.useState(void 0);return(0,U.jsx)(gl,{scope:t,anchor:r,onAnchorChange:i,placementState:a,setPlacementState:o,children:n})},`Popper`),yl=`PopperAnchor`,bl=_.forwardRef(fl(function(e,t){let{__scopePopper:n,virtualRef:r,...i}=e,a=_l(yl,n),o=_.useRef(null),s=a.onAnchorChange,c=Nt(t,_.useCallback(e=>{o.current=e,e&&s(e)},[s])),l=_.useRef(null);_.useEffect(()=>{if(!r)return;let e=l.current;l.current=r.current,e!==l.current&&s(l.current)});let u=a.placementState&&Al(a.placementState),d=u?.[0],f=u?.[1];return r?null:(0,U.jsx)(W.div,{"data-radix-popper-side":d,"data-radix-popper-align":f,...i,ref:c})},`PopperAnchor`)),xl=`PopperContent`,[Sl,Cl]=ml(xl),wl=_.forwardRef(fl(function(e,t){let{__scopePopper:n,side:r=`bottom`,sideOffset:i=0,align:a=`center`,alignOffset:o=0,arrowPadding:s=0,avoidCollisions:c=!0,collisionBoundary:l=[],collisionPadding:u=0,sticky:d=`partial`,hideWhenDetached:f=!1,updatePositionStrategy:p=`optimized`,onPlaced:m,...h}=e,g=_l(xl,n),[v,y]=_.useState(null),b=Nt(t,y),[x,S]=_.useState(null),C=No(x),w=C?.width??0,T=C?.height??0,E=r+(a===`center`?``:`-`+a),D=typeof u==`number`?u:{top:0,right:0,bottom:0,left:0,...u},O=Array.isArray(l)?l:[l],k=O.length>0,ee={padding:D,boundary:O.filter(Ol),altBoundary:k},{refs:A,floatingStyles:j,placement:M,isPositioned:N,middlewareData:P}=el({strategy:`fixed`,placement:E,whileElementsMounted:fl((...e)=>Bc(...e,{animationFrame:p===`always`}),`whileElementsMounted`),elements:{reference:g.anchor},middleware:[nl({mainAxis:i+T,alignmentAxis:o}),c&&rl({mainAxis:!0,crossAxis:!1,limiter:d===`partial`?il():void 0,...ee}),c&&al({...ee}),ol({...ee,apply:fl(({elements:e,rects:t,availableWidth:n,availableHeight:r})=>{let{width:i,height:a}=t.reference,o=e.floating.style;o.setProperty(`--radix-popper-available-width`,`${n}px`),o.setProperty(`--radix-popper-available-height`,`${r}px`),o.setProperty(`--radix-popper-anchor-width`,`${i}px`),o.setProperty(`--radix-popper-anchor-height`,`${a}px`)},`apply`)}),x&&cl({element:x,padding:s}),kl({arrowWidth:w,arrowHeight:T}),f&&sl({strategy:`referenceHidden`,...ee,boundary:k?ee.boundary:void 0})]}),F=g.setPlacementState;jn(()=>(F(M),()=>{F(void 0)}),[M,F]);let[I,te]=Al(M),ne=Er(m);jn(()=>{N&&ne?.()},[N,ne]);let re=P.arrow?.x,ie=P.arrow?.y,L=P.arrow?.centerOffset!==0,[R,ae]=_.useState();return jn(()=>{v&&ae(window.getComputedStyle(v).zIndex)},[v]),(0,U.jsx)(`div`,{ref:A.setFloating,"data-radix-popper-content-wrapper":``,style:{...j,transform:N?j.transform:`translate(0, -200%)`,minWidth:`max-content`,zIndex:R,"--radix-popper-transform-origin":[P.transformOrigin?.x,P.transformOrigin?.y].join(` `),...P.hide?.referenceHidden&&{visibility:`hidden`,pointerEvents:`none`}},dir:e.dir,children:(0,U.jsx)(Sl,{scope:n,placedSide:I,placedAlign:te,onArrowChange:S,arrowX:re,arrowY:ie,shouldHideArrow:L,children:(0,U.jsx)(W.div,{"data-side":I,"data-align":te,...h,ref:b,style:{...h.style,animation:N?h.style?.animation:`none`}})})})},`PopperContent`)),Tl=`PopperArrow`,El={top:`bottom`,right:`left`,bottom:`top`,left:`right`},Dl=_.forwardRef(fl(function(e,t){let{__scopePopper:n,...r}=e,i=Cl(Tl,n),a=El[i.placedSide];return(0,U.jsx)(`span`,{ref:i.onArrowChange,style:{position:`absolute`,left:i.arrowX,top:i.arrowY,[a]:0,transformOrigin:{top:``,right:`0 0`,bottom:`center 0`,left:`100% 0`}[i.placedSide],transform:{top:`translateY(100%)`,right:`translateY(50%) rotate(90deg) translateX(-50%)`,bottom:`rotate(180deg)`,left:`translateY(50%) rotate(-90deg) translateX(50%)`}[i.placedSide],visibility:i.shouldHideArrow?`hidden`:void 0},children:(0,U.jsx)(ul,{...r,ref:t,style:{...r.style,display:`block`}})})},`PopperArrow`));function Ol(e){return e!==null}fl(Ol,`isNotNull`);var kl=fl(e=>({name:`transformOrigin`,options:e,fn(t){let{placement:n,rects:r,middlewareData:i}=t,a=i.arrow?.centerOffset!==0,o=a?0:e.arrowWidth,s=a?0:e.arrowHeight,[c,l]=Al(n),u={start:`0%`,center:`50%`,end:`100%`}[l],d=(i.arrow?.x??0)+o/2,f=(i.arrow?.y??0)+s/2,p=``,m=``;return c===`bottom`?(p=a?u:`${d}px`,m=`${-s}px`):c===`top`?(p=a?u:`${d}px`,m=`${r.floating.height+s}px`):c===`right`?(p=`${-s}px`,m=a?u:`${f}px`):c===`left`&&(p=`${r.floating.width+s}px`,m=a?u:`${f}px`),{data:{x:p,y:m}}}}),`transformOrigin`);function Al(e){let[t,n=`center`]=e.split(`-`);return[t,n]}fl(Al,`getSideAndAlignFromPlacement`);var jl=vl,Ml=bl,Nl=wl,Pl=Dl,Fl=Object.defineProperty,Y=(e,t)=>Fl(e,`name`,{value:t,configurable:!0}),Il=!1;function X(){let[e,t]=_.useState(Il);return _.useEffect(()=>{Il||(Il=!0,t(!0))},[]),e}Y(X,`useIsHydrated`);var Z=_.useSyncExternalStore;function Ll(){return()=>{}}Y(Ll,`subscribe`);function Rl(){return Z(Ll,()=>!0,()=>!1)}Y(Rl,`useIsHydratedModern`);var zl=typeof Z==`function`?Rl:X,Bl=Object.defineProperty,Vl=(e,t)=>Bl(e,`name`,{value:t,configurable:!0}),Hl=`rovingFocusGroup.onEntryFocus`,Ul={bubbles:!1,cancelable:!0},Wl=`RovingFocusGroup`,[Gl,Kl,ql]=pn(Wl),[Jl,Yl]=ln(Wl,[ql]),[Xl,Zl]=Jl(Wl),Ql=_.forwardRef(Vl(function(e,t){return(0,U.jsx)(Gl.Provider,{scope:e.__scopeRovingFocusGroup,children:(0,U.jsx)(Gl.Slot,{scope:e.__scopeRovingFocusGroup,children:(0,U.jsx)($l,{...e,ref:t})})})},`RovingFocusGroup`)),$l=_.forwardRef(Vl(function(e,t){let{__scopeRovingFocusGroup:n,orientation:r,loop:i=!1,dir:a,currentTabStopId:o,defaultCurrentTabStopId:s,onCurrentTabStopIdChange:c,onEntryFocus:l,preventScrollOnEntryFocus:u=!1,...d}=e,f=_.useRef(null),p=Nt(t,f),m=Cr(a),[h,g]=Bn({prop:o,defaultProp:s??null,onChange:c,caller:Wl}),[v,y]=_.useState(!1),b=Er(l),x=Kl(n),S=_.useRef(!1),[C,w]=_.useState(0);return _.useEffect(()=>{let e=f.current;if(e)return e.addEventListener(Hl,b),()=>e.removeEventListener(Hl,b)},[b]),(0,U.jsx)(Xl,{scope:n,orientation:r,dir:m,loop:i,currentTabStopId:h,onItemFocus:_.useCallback(e=>g(e),[g]),onItemShiftTab:_.useCallback(()=>y(!0),[]),onFocusableItemAdd:_.useCallback(()=>w(e=>e+1),[]),onFocusableItemRemove:_.useCallback(()=>w(e=>e-1),[]),children:(0,U.jsx)(W.div,{tabIndex:v||C===0?-1:0,"data-orientation":r,...d,ref:p,style:{outline:`none`,...e.style},onMouseDown:G(e.onMouseDown,()=>{S.current=!0}),onFocus:G(e.onFocus,e=>{let t=!S.current;if(e.target===e.currentTarget&&t&&!v){let t=new CustomEvent(Hl,Ul);if(e.currentTarget.dispatchEvent(t),!t.defaultPrevented){let e=x().filter(e=>e.focusable);au([e.find(e=>e.active),e.find(e=>e.id===h),...e].filter(Boolean).map(e=>e.ref.current),u)}}S.current=!1}),onBlur:G(e.onBlur,()=>y(!1))})})},`RovingFocusGroupImpl`)),eu=`RovingFocusGroupItem`,tu=_.forwardRef(Vl(function(e,t){let{__scopeRovingFocusGroup:n,focusable:r=!0,active:i=!1,tabStopId:a,children:o,...s}=e,c=ir(),l=a||c,u=Zl(eu,n),d=u.currentTabStopId===l,f=Kl(n),{onFocusableItemAdd:p,onFocusableItemRemove:m,currentTabStopId:h}=u,g=zl();return jn(()=>{if(!(!g||!r))return p(),()=>m()},[g,r,p,m]),_.useEffect(()=>{if(!(g||!r))return p(),()=>m()},[g,r,p,m]),(0,U.jsx)(Gl.ItemSlot,{scope:n,id:l,focusable:r,active:i,children:(0,U.jsx)(W.span,{tabIndex:d?0:-1,"data-orientation":u.orientation,...s,ref:t,onMouseDown:G(e.onMouseDown,e=>{r?u.onItemFocus(l):e.preventDefault()}),onFocus:G(e.onFocus,()=>u.onItemFocus(l)),onKeyDown:G(e.onKeyDown,e=>{if(e.key===`Tab`&&e.shiftKey){u.onItemShiftTab();return}if(e.target!==e.currentTarget)return;let t=iu(e,u.orientation,u.dir);if(t!==void 0){if(e.metaKey||e.ctrlKey||e.altKey||e.shiftKey)return;e.preventDefault();let n=f().filter(e=>e.focusable).map(e=>e.ref.current);if(t===`last`)n.reverse();else if(t===`prev`||t===`next`){t===`prev`&&n.reverse();let r=n.indexOf(e.currentTarget);n=u.loop?ou(n,r+1):n.slice(r+1)}setTimeout(()=>au(n))}}),children:typeof o==`function`?o({isCurrentTabStop:d,hasTabStop:h!=null}):o})})},`RovingFocusGroupItem`)),nu={ArrowLeft:`prev`,ArrowUp:`prev`,ArrowRight:`next`,ArrowDown:`next`,PageUp:`first`,Home:`first`,PageDown:`last`,End:`last`};function ru(e,t){return t===`rtl`?e===`ArrowLeft`?`ArrowRight`:e===`ArrowRight`?`ArrowLeft`:e:e}Vl(ru,`getDirectionAwareKey`);function iu(e,t,n){let r=ru(e.key,n);if(!(t===`vertical`&&[`ArrowLeft`,`ArrowRight`].includes(r))&&!(t===`horizontal`&&[`ArrowUp`,`ArrowDown`].includes(r)))return nu[r]}Vl(iu,`getFocusIntent`);function au(e,t=!1){let n=document.activeElement;for(let r of e)if(r===n||(r.focus({preventScroll:t}),document.activeElement!==n))return}Vl(au,`focusFirst`);function ou(e,t){return e.map((n,r)=>e[(t+r)%e.length])}Vl(ou,`wrapArray`);var su=Ql,cu=tu,lu=Object.defineProperty,Q=(e,t)=>lu(e,`name`,{value:t,configurable:!0}),uu=[`Enter`,` `],du=[`ArrowDown`,`PageUp`,`Home`],fu=[`ArrowUp`,`PageDown`,`End`],pu=[...du,...fu];[...uu],[...uu];var mu=`Menu`,[hu,gu,_u]=pn(mu),[vu,yu]=ln(mu,[_u,hl,Yl]),bu=hl(),xu=Yl(),[Su,Cu]=vu(mu),[wu,Tu]=vu(mu),Eu=Q(e=>{let{__scopeMenu:t,open:n=!1,children:r,dir:i,onOpenChange:a,modal:o=!0}=e,s=bu(t),[c,l]=_.useState(null),u=_.useRef(!1),d=Er(a),f=Cr(i);return _.useEffect(()=>{let e=Q(()=>{u.current=!0,document.addEventListener(`pointerdown`,t,{capture:!0,once:!0}),document.addEventListener(`pointermove`,t,{capture:!0,once:!0})},`handleKeyDown`),t=Q(()=>u.current=!1,`handlePointer`);return document.addEventListener(`keydown`,e,{capture:!0}),()=>{document.removeEventListener(`keydown`,e,{capture:!0}),document.removeEventListener(`pointerdown`,t,{capture:!0}),document.removeEventListener(`pointermove`,t,{capture:!0})}},[]),_.useEffect(()=>{if(!n)return;let e=Q(()=>d(!1),`handleBlur`);return window.addEventListener(`blur`,e),()=>window.removeEventListener(`blur`,e)},[n,d]),(0,U.jsx)(jl,{...s,children:(0,U.jsx)(Su,{scope:t,open:n,onOpenChange:d,content:c,onContentChange:l,children:(0,U.jsx)(wu,{scope:t,onClose:_.useCallback(()=>d(!1),[d]),isUsingKeyboardRef:u,dir:f,modal:o,children:r})})})},`Menu`),Du=_.forwardRef(Q(function(e,t){let{__scopeMenu:n,...r}=e,i=bu(n);return(0,U.jsx)(Ml,{...i,...r,ref:t})},`MenuAnchor`)),Ou=`MenuPortal`,[ku,Au]=vu(Ou,{forceMount:void 0}),ju=Q(e=>{let{__scopeMenu:t,forceMount:n,children:r,container:i}=e,a=Cu(Ou,t);return(0,U.jsx)(ku,{scope:t,forceMount:n,children:(0,U.jsx)(Jn,{present:n||a.open,children:(0,U.jsx)(ai,{asChild:!0,container:i,children:r})})})},`MenuPortal`),Mu=`MenuContent`,[Nu,Pu]=vu(Mu),Fu=_.forwardRef(Q(function(e,t){let n=Au(Mu,e.__scopeMenu),{forceMount:r=n.forceMount,...i}=e,a=Cu(Mu,e.__scopeMenu),o=Tu(Mu,e.__scopeMenu);return(0,U.jsx)(hu.Provider,{scope:e.__scopeMenu,children:(0,U.jsx)(Jn,{present:r||a.open,children:(0,U.jsx)(hu.Slot,{scope:e.__scopeMenu,children:o.modal?(0,U.jsx)(Iu,{...i,ref:t}):(0,U.jsx)(Lu,{...i,ref:t})})})})},`MenuContent`)),Iu=_.forwardRef(Q(function(e,t){let n=Cu(Mu,e.__scopeMenu),r=_.useRef(null),i=Nt(t,r);return _.useEffect(()=>{let e=r.current;if(e)return ka(e)},[]),(0,U.jsx)(zu,{...e,ref:i,trapFocus:n.open,disableOutsidePointerEvents:n.open,disableOutsideScroll:!0,onFocusOutside:G(e.onFocusOutside,e=>e.preventDefault(),{checkForDefaultPrevented:!1}),onDismiss:()=>n.onOpenChange(!1)})},`MenuRootContentModal`)),Lu=_.forwardRef(Q(function(e,t){let n=Cu(Mu,e.__scopeMenu);return(0,U.jsx)(zu,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,disableOutsideScroll:!1,onDismiss:()=>n.onOpenChange(!1)})},`MenuRootContentNonModal`)),Ru=Lt(`MenuContent.ScrollLock`),zu=_.forwardRef(Q(function(e,t){let{__scopeMenu:n,loop:r=!1,trapFocus:i,onOpenAutoFocus:a,onCloseAutoFocus:o,disableOutsidePointerEvents:s,onEntryFocus:c,onEscapeKeyDown:l,onPointerDownOutside:u,onFocusOutside:d,onInteractOutside:f,onDismiss:p,disableOutsideScroll:m,...h}=e,g=Cu(Mu,n),v=Tu(Mu,n),y=bu(n),b=xu(n),x=gu(n),[S,C]=_.useState(null),w=_.useRef(null),T=Nt(t,w,g.onContentChange),E=_.useRef(0),D=_.useRef(``),O=_.useRef(0),k=_.useRef(null),ee=_.useRef(`right`),A=_.useRef(0),j=m?ba:_.Fragment,M=m?{as:Ru,allowPinchZoom:!0}:void 0,N=Q(e=>{let t=D.current+e,n=x().filter(e=>!e.disabled),r=document.activeElement,i=n.find(e=>e.ref.current===r)?.textValue,a=od(n.map(e=>e.textValue),t,i),o=n.find(e=>e.textValue===a)?.ref.current;Q((function e(t){D.current=t,window.clearTimeout(E.current),t!==``&&(E.current=window.setTimeout(()=>e(``),1e3))}),`updateSearch`)(t),o&&setTimeout(()=>o.focus())},`handleTypeaheadSearch`);_.useEffect(()=>()=>window.clearTimeout(E.current),[]),di();let P=_.useCallback(e=>ee.current===k.current?.side&&cd(e,k.current?.area),[]);return(0,U.jsx)(Nu,{scope:n,searchRef:D,onItemEnter:_.useCallback(e=>{P(e)&&e.preventDefault()},[P]),onItemLeave:_.useCallback(e=>{P(e)||(w.current?.focus(),C(null))},[P]),onTriggerLeave:_.useCallback(e=>{P(e)&&e.preventDefault()},[P]),pointerGraceTimerRef:O,onPointerGraceIntentChange:_.useCallback(e=>{k.current=e},[]),children:(0,U.jsx)(j,{...M,children:(0,U.jsx)(Kr,{asChild:!0,trapped:i,onMountAutoFocus:G(a,e=>{e.preventDefault(),w.current?.focus({preventScroll:!0})}),onUnmountAutoFocus:o,children:(0,U.jsx)(Pr,{asChild:!0,disableOutsidePointerEvents:s,onEscapeKeyDown:l,onPointerDownOutside:u,onFocusOutside:d,onInteractOutside:f,onDismiss:p,children:(0,U.jsx)(su,{asChild:!0,...b,dir:v.dir,orientation:`vertical`,loop:r,currentTabStopId:S,onCurrentTabStopIdChange:C,onEntryFocus:G(c,e=>{v.isUsingKeyboardRef.current||e.preventDefault()}),preventScrollOnEntryFocus:!0,children:(0,U.jsx)(Nl,{role:`menu`,"aria-orientation":`vertical`,"data-state":td(g.open),"data-radix-menu-content":``,dir:v.dir,...y,...h,ref:T,style:{outline:`none`,...h.style},onKeyDown:G(h.onKeyDown,e=>{let t=e.target.closest(`[data-radix-menu-content]`)===e.currentTarget,n=e.ctrlKey||e.altKey||e.metaKey,r=e.key.length===1;t&&(e.key===`Tab`&&e.preventDefault(),!n&&r&&N(e.key));let i=w.current;if(e.target!==i||!pu.includes(e.key))return;e.preventDefault();let a=x().filter(e=>!e.disabled).map(e=>e.ref.current);fu.includes(e.key)&&a.reverse(),id(a)}),onBlur:G(e.onBlur,e=>{e.currentTarget.contains(e.target)||(window.clearTimeout(E.current),D.current=``)}),onPointerMove:G(e.onPointerMove,ld(e=>{let t=e.target,n=A.current!==e.clientX;if(e.currentTarget.contains(t)&&n){let t=e.clientX>A.current?`right`:`left`;ee.current=t,A.current=e.clientX}}))})})})})})})},`MenuContentImpl`)),Bu=_.forwardRef(Q(function(e,t){let{__scopeMenu:n,...r}=e;return(0,U.jsx)(W.div,{role:`group`,...r,ref:t})},`MenuGroup`)),Vu=_.forwardRef(Q(function(e,t){let{__scopeMenu:n,...r}=e;return(0,U.jsx)(W.div,{...r,ref:t})},`MenuLabel`)),Hu=`MenuItem`,Uu=`menu.itemSelect`,Wu=_.forwardRef(Q(function(e,t){let{disabled:n=!1,onSelect:r,...i}=e,a=_.useRef(null),o=Tu(Hu,e.__scopeMenu),s=Pu(Hu,e.__scopeMenu),c=Nt(t,a),l=_.useRef(!1),u=Q(()=>{let e=a.current;if(!n&&e){let t=new CustomEvent(Uu,{bubbles:!0,cancelable:!0});e.addEventListener(Uu,e=>r?.(e),{once:!0}),en(e,t),t.defaultPrevented?l.current=!1:o.onClose()}},`handleSelect`);return(0,U.jsx)(Gu,{...i,ref:c,disabled:n,onClick:G(e.onClick,u),onPointerDown:t=>{e.onPointerDown?.(t),l.current=!0},onPointerUp:G(e.onPointerUp,e=>{l.current||e.currentTarget?.click()}),onKeyDown:G(e.onKeyDown,e=>{n||e.target!==e.currentTarget||(s.searchRef.current===``||e.key!==` `)&&uu.includes(e.key)&&(e.currentTarget.click(),e.preventDefault())})})},`MenuItem`)),Gu=_.forwardRef(Q(function(e,t){let{__scopeMenu:n,disabled:r=!1,textValue:i,...a}=e,o=Pu(Hu,n),s=xu(n),c=_.useRef(null),l=Nt(t,c),[u,d]=_.useState(!1),[f,p]=_.useState(``);return _.useEffect(()=>{let e=c.current;e&&p((e.textContent??``).trim())},[a.children]),(0,U.jsx)(hu.ItemSlot,{scope:n,disabled:r,textValue:i??f,children:(0,U.jsx)(cu,{asChild:!0,...s,focusable:!r,children:(0,U.jsx)(W.div,{role:`menuitem`,"data-highlighted":u?``:void 0,"aria-disabled":r||void 0,"data-disabled":r?``:void 0,...a,ref:l,onPointerMove:G(e.onPointerMove,ld(e=>{r?o.onItemLeave(e):(o.onItemEnter(e),e.defaultPrevented||e.currentTarget.focus({preventScroll:!0}))})),onPointerLeave:G(e.onPointerLeave,ld(e=>o.onItemLeave(e))),onFocus:G(e.onFocus,()=>d(!0)),onBlur:G(e.onBlur,()=>d(!1))})})})},`MenuItemImpl`)),Ku=_.forwardRef(Q(function(e,t){let{checked:n=!1,onCheckedChange:r,...i}=e;return(0,U.jsx)(Xu,{scope:e.__scopeMenu,checked:n,children:(0,U.jsx)(Wu,{role:`menuitemcheckbox`,"aria-checked":nd(n)?`mixed`:n,...i,ref:t,"data-state":rd(n),onSelect:G(i.onSelect,()=>r?.(nd(n)?!0:!n),{checkForDefaultPrevented:!1})})})},`MenuCheckboxItem`)),[qu,Ju]=vu(`MenuRadioGroup`,{value:void 0,onValueChange:Q(()=>{},`onValueChange`)}),Yu=`MenuItemIndicator`,[Xu,Zu]=vu(Yu,{checked:!1}),Qu=_.forwardRef(Q(function(e,t){let{__scopeMenu:n,forceMount:r,...i}=e,a=Zu(Yu,n);return(0,U.jsx)(Jn,{present:r||nd(a.checked)||a.checked===!0,children:(0,U.jsx)(W.span,{...i,ref:t,"data-state":rd(a.checked)})})},`MenuItemIndicator`)),[$u,ed]=vu(`MenuSub`);function td(e){return e?`open`:`closed`}Q(td,`getOpenState`);function nd(e){return e===`indeterminate`}Q(nd,`isIndeterminate`);function rd(e){return nd(e)?`indeterminate`:e?`checked`:`unchecked`}Q(rd,`getCheckedState`);function id(e){let t=document.activeElement;for(let n of e)if(n===t||(n.focus(),document.activeElement!==t))return}Q(id,`focusFirst`);function ad(e,t){return e.map((n,r)=>e[(t+r)%e.length])}Q(ad,`wrapArray`);function od(e,t,n){let r=t.length>1&&Array.from(t).every(e=>e===t[0])?t[0]:t,i=n?e.indexOf(n):-1,a=ad(e,Math.max(i,0));r.length===1&&(a=a.filter(e=>e!==n));let o=a.find(e=>e.toLowerCase().startsWith(r.toLowerCase()));return o===n?void 0:o}Q(od,`getNextMatch`);function sd(e,t){let{x:n,y:r}=e,i=!1;for(let e=0,a=t.length-1;er!=d>r&&n<(u-c)*(r-l)/(d-l)+c&&(i=!i)}return i}Q(sd,`isPointInPolygon`);function cd(e,t){return t?sd({x:e.clientX,y:e.clientY},t):!1}Q(cd,`isPointerInGraceArea`);function ld(e){return t=>t.pointerType===`mouse`?e(t):void 0}Q(ld,`whenMouse`);var ud=Eu,dd=Du,fd=ju,pd=Fu,md=Bu,hd=Vu,gd=Ku,_d=Qu,vd=Object.defineProperty,$=(e,t)=>vd(e,`name`,{value:t,configurable:!0}),yd=`DropdownMenu`,[bd,xd]=ln(yd,[yu]),Sd=yu(),[Cd,wd]=bd(yd),Td=$(e=>{let{__scopeDropdownMenu:t,children:n,dir:r,open:i,defaultOpen:a,onOpenChange:o,modal:s=!0}=e,c=Sd(t),l=_.useRef(null),[u,d]=Bn({prop:i,defaultProp:a??!1,onChange:o,caller:yd});return(0,U.jsx)(Cd,{scope:t,triggerId:ir(),triggerRef:l,contentId:ir(),open:u,onOpenChange:d,onOpenToggle:_.useCallback(()=>d(e=>!e),[d]),modal:s,children:(0,U.jsx)(ud,{...c,open:u,onOpenChange:d,dir:r,modal:s,children:n})})},`DropdownMenu`),Ed=`DropdownMenuTrigger`,Dd=_.forwardRef($(function(e,t){let{__scopeDropdownMenu:n,disabled:r=!1,...i}=e,a=wd(Ed,n),o=Sd(n),s=Nt(t,a.triggerRef);return(0,U.jsx)(dd,{asChild:!0,...o,children:(0,U.jsx)(W.button,{type:`button`,id:a.triggerId,"aria-haspopup":`menu`,"aria-expanded":a.open,"aria-controls":a.open?a.contentId:void 0,"data-state":a.open?`open`:`closed`,"data-disabled":r?``:void 0,disabled:r,...i,ref:s,onPointerDown:G(e.onPointerDown,e=>{!r&&e.button===0&&e.ctrlKey===!1&&(a.onOpenToggle(),a.open||e.preventDefault())}),onKeyDown:G(e.onKeyDown,e=>{r||([`Enter`,` `].includes(e.key)&&a.onOpenToggle(),e.key===`ArrowDown`&&a.onOpenChange(!0),[`Enter`,` `,`ArrowDown`].includes(e.key)&&e.preventDefault())})})})},`DropdownMenuTrigger`)),Od=$(e=>{let{__scopeDropdownMenu:t,...n}=e,r=Sd(t);return(0,U.jsx)(fd,{...r,...n})},`DropdownMenuPortal`),kd=`DropdownMenuContent`,Ad=_.forwardRef($(function(e,t){let{__scopeDropdownMenu:n,...r}=e,i=wd(kd,n),a=Sd(n),o=_.useRef(!1);return(0,U.jsx)(pd,{id:i.contentId,"aria-labelledby":i.triggerId,...a,...r,ref:t,onCloseAutoFocus:G(e.onCloseAutoFocus,e=>{o.current||i.triggerRef.current?.focus(),o.current=!1,e.preventDefault()}),onInteractOutside:G(e.onInteractOutside,e=>{let t=e.detail.originalEvent,n=t.button===0&&t.ctrlKey===!0,r=t.button===2||n;(!i.modal||r)&&(o.current=!0)}),style:{...e.style,"--radix-dropdown-menu-content-transform-origin":`var(--radix-popper-transform-origin)`,"--radix-dropdown-menu-content-available-width":`var(--radix-popper-available-width)`,"--radix-dropdown-menu-content-available-height":`var(--radix-popper-available-height)`,"--radix-dropdown-menu-trigger-width":`var(--radix-popper-anchor-width)`,"--radix-dropdown-menu-trigger-height":`var(--radix-popper-anchor-height)`}})},`DropdownMenuContent`)),jd=_.forwardRef($(function(e,t){let{__scopeDropdownMenu:n,...r}=e,i=Sd(n);return(0,U.jsx)(md,{...i,...r,ref:t})},`DropdownMenuGroup`)),Md=_.forwardRef($(function(e,t){let{__scopeDropdownMenu:n,...r}=e,i=Sd(n);return(0,U.jsx)(hd,{...i,...r,ref:t})},`DropdownMenuLabel`)),Nd=_.forwardRef($(function(e,t){let{__scopeDropdownMenu:n,...r}=e,i=Sd(n);return(0,U.jsx)(gd,{...i,...r,ref:t})},`DropdownMenuCheckboxItem`)),Pd=_.forwardRef($(function(e,t){let{__scopeDropdownMenu:n,...r}=e,i=Sd(n);return(0,U.jsx)(_d,{...i,...r,ref:t})},`DropdownMenuItemIndicator`)),Fd=Td,Id=Dd,Ld=Od,Rd=Ad,zd=jd,Bd=Md,Vd=Nd,Hd=Pd,Ud=Object.defineProperty,Wd=_.forwardRef(((e,t)=>Ud(e,`name`,{value:t,configurable:!0}))(function(e,t){return(0,U.jsx)(W.label,{...e,ref:t,onMouseDown:t=>{t.target.closest(`button, input, select, textarea`)||(e.onMouseDown?.(t),!t.defaultPrevented&&t.detail>1&&t.preventDefault())}})},`Label`)),Gd=Object.defineProperty,Kd=(e,t)=>Gd(e,`name`,{value:t,configurable:!0}),qd=`Popover`,[Jd,Yd]=ln(qd,[hl]),Xd=hl(),[Zd,Qd]=Jd(qd),$d=Kd(e=>{let{__scopePopover:t,children:n,open:r,defaultOpen:i,onOpenChange:a,modal:o=!1}=e,s=Xd(t),c=_.useRef(null),[l,u]=_.useState(!1),[d,f]=Bn({prop:r,defaultProp:i??!1,onChange:a,caller:qd});return(0,U.jsx)(jl,{...s,children:(0,U.jsx)(Zd,{scope:t,contentId:ir(),triggerRef:c,open:d,onOpenChange:f,onOpenToggle:_.useCallback(()=>f(e=>!e),[f]),hasCustomAnchor:l,onCustomAnchorAdd:_.useCallback(()=>u(!0),[]),onCustomAnchorRemove:_.useCallback(()=>u(!1),[]),modal:o,children:n})})},`Popover`),ef=`PopoverTrigger`,tf=_.forwardRef(Kd(function(e,t){let{__scopePopover:n,...r}=e,i=Qd(ef,n),a=Xd(n),o=Nt(t,i.triggerRef),s=(0,U.jsx)(W.button,{type:`button`,"aria-haspopup":`dialog`,"aria-expanded":i.open,"aria-controls":i.open?i.contentId:void 0,"data-state":pf(i.open),...r,ref:o,onClick:G(e.onClick,i.onOpenToggle)});return i.hasCustomAnchor?s:(0,U.jsx)(Ml,{asChild:!0,...a,children:s})},`PopoverTrigger`)),nf=`PopoverPortal`,[rf,af]=Jd(nf,{forceMount:void 0}),of=Kd(e=>{let{__scopePopover:t,forceMount:n,children:r,container:i}=e,a=Qd(nf,t);return(0,U.jsx)(rf,{scope:t,forceMount:n,children:(0,U.jsx)(Jn,{present:n||a.open,children:(0,U.jsx)(ai,{asChild:!0,container:i,children:r})})})},`PopoverPortal`),sf=`PopoverContent`,cf=_.forwardRef(Kd(function(e,t){let n=af(sf,e.__scopePopover),{forceMount:r=n.forceMount,...i}=e,a=Qd(sf,e.__scopePopover);return(0,U.jsx)(Jn,{present:r||a.open,children:a.modal?(0,U.jsx)(uf,{...i,ref:t}):(0,U.jsx)(df,{...i,ref:t})})},`PopoverContent`)),lf=Lt(`PopoverContent.RemoveScroll`),uf=_.forwardRef(Kd(function(e,t){let n=Qd(sf,e.__scopePopover),r=_.useRef(null),i=Nt(t,r),a=_.useRef(!1);return _.useEffect(()=>{let e=r.current;if(e)return ka(e)},[]),(0,U.jsx)(ba,{as:lf,allowPinchZoom:!0,children:(0,U.jsx)(ff,{...e,ref:i,trapFocus:n.open,disableOutsidePointerEvents:!0,onCloseAutoFocus:G(e.onCloseAutoFocus,e=>{e.preventDefault(),a.current||n.triggerRef.current?.focus()}),onPointerDownOutside:G(e.onPointerDownOutside,e=>{let t=e.detail.originalEvent,n=t.button===0&&t.ctrlKey===!0,r=t.button===2||n;a.current=r},{checkForDefaultPrevented:!1}),onFocusOutside:G(e.onFocusOutside,e=>e.preventDefault(),{checkForDefaultPrevented:!1})})})},`PopoverContentModal`)),df=_.forwardRef(Kd(function(e,t){let n=Qd(sf,e.__scopePopover),r=_.useRef(!1),i=_.useRef(!1);return(0,U.jsx)(ff,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:t=>{e.onCloseAutoFocus?.(t),t.defaultPrevented||(r.current||n.triggerRef.current?.focus(),t.preventDefault()),r.current=!1,i.current=!1},onInteractOutside:t=>{e.onInteractOutside?.(t),t.defaultPrevented||(r.current=!0,t.detail.originalEvent.type===`pointerdown`&&(i.current=!0));let a=t.target;n.triggerRef.current?.contains(a)&&t.preventDefault(),t.detail.originalEvent.type===`focusin`&&i.current&&t.preventDefault()}})},`PopoverContentNonModal`)),ff=_.forwardRef(Kd(function(e,t){let{__scopePopover:n,trapFocus:r,onOpenAutoFocus:i,onCloseAutoFocus:a,disableOutsidePointerEvents:o,onEscapeKeyDown:s,onPointerDownOutside:c,onFocusOutside:l,onInteractOutside:u,...d}=e,f=Qd(sf,n),p=Xd(n);return di(),(0,U.jsx)(Kr,{asChild:!0,loop:!0,trapped:r,onMountAutoFocus:i,onUnmountAutoFocus:a,children:(0,U.jsx)(Pr,{asChild:!0,disableOutsidePointerEvents:o,onInteractOutside:u,onEscapeKeyDown:s,onPointerDownOutside:c,onFocusOutside:l,onDismiss:()=>f.onOpenChange(!1),deferPointerDownOutside:!0,children:(0,U.jsx)(Nl,{"data-state":pf(f.open),role:`dialog`,id:f.contentId,...p,...d,ref:t,style:{...d.style,"--radix-popover-content-transform-origin":`var(--radix-popper-transform-origin)`,"--radix-popover-content-available-width":`var(--radix-popper-available-width)`,"--radix-popover-content-available-height":`var(--radix-popper-available-height)`,"--radix-popover-trigger-width":`var(--radix-popper-anchor-width)`,"--radix-popover-trigger-height":`var(--radix-popper-anchor-height)`}})})})},`PopoverContentImpl`));function pf(e){return e?`open`:`closed`}Kd(pf,`getState`);var mf=$d,hf=tf,gf=of,_f=cf,vf=Object.defineProperty,yf=(e,t)=>vf(e,`name`,{value:t,configurable:!0}),bf=`Tabs`,[xf,Sf]=ln(bf,[Yl]),Cf=Yl(),[wf,Tf]=xf(bf),Ef=_.forwardRef(yf(function(e,t){let{__scopeTabs:n,value:r,onValueChange:i,defaultValue:a,orientation:o=`horizontal`,dir:s,activationMode:c=`automatic`,...l}=e,u=Cr(s),[d,f]=Bn({prop:r,onChange:i,defaultProp:a??``,caller:bf});return(0,U.jsx)(wf,{scope:n,baseId:ir(),value:d,onValueChange:f,orientation:o,dir:u,activationMode:c,children:(0,U.jsx)(W.div,{dir:u,"data-orientation":o,...l,ref:t})})},`Tabs`)),Df=`TabsList`,Of=_.forwardRef(yf(function(e,t){let{__scopeTabs:n,loop:r=!0,...i}=e,a=Tf(Df,n),o=Cf(n);return(0,U.jsx)(su,{asChild:!0,...o,orientation:a.orientation,dir:a.dir,loop:r,children:(0,U.jsx)(W.div,{role:`tablist`,"aria-orientation":a.orientation,...i,ref:t})})},`TabsList`)),kf=`TabsTrigger`,Af=_.forwardRef(yf(function(e,t){let{__scopeTabs:n,value:r,disabled:i=!1,...a}=e,o=Tf(kf,n),s=Cf(n),c=Nf(o.baseId,r),l=Pf(o.baseId,r),u=r===o.value;return(0,U.jsx)(cu,{asChild:!0,...s,focusable:!i,active:u,children:(0,U.jsx)(W.button,{type:`button`,role:`tab`,"aria-selected":u,"aria-controls":l,"data-state":u?`active`:`inactive`,"data-disabled":i?``:void 0,disabled:i,id:c,...a,ref:t,onMouseDown:G(e.onMouseDown,e=>{!i&&e.button===0&&e.ctrlKey===!1?o.onValueChange(r):e.preventDefault()}),onKeyDown:G(e.onKeyDown,e=>{i||e.target!==e.currentTarget||[` `,`Enter`].includes(e.key)&&o.onValueChange(r)}),onFocus:G(e.onFocus,()=>{let e=o.activationMode!==`manual`;!u&&!i&&e&&o.onValueChange(r)})})})},`TabsTrigger`)),jf=`TabsContent`,Mf=_.forwardRef(yf(function(e,t){let{__scopeTabs:n,value:r,forceMount:i,children:a,...o}=e,s=Tf(jf,n),c=Nf(s.baseId,r),l=Pf(s.baseId,r),u=r===s.value,d=_.useRef(u);return _.useEffect(()=>{let e=requestAnimationFrame(()=>d.current=!1);return()=>cancelAnimationFrame(e)},[]),(0,U.jsx)(Jn,{present:i||u,children:({present:n})=>(0,U.jsx)(W.div,{"data-state":u?`active`:`inactive`,"data-orientation":s.orientation,role:`tabpanel`,"aria-labelledby":c,hidden:!n,id:l,tabIndex:0,...o,ref:t,style:{...e.style,animationDuration:d.current?`0s`:void 0},children:n&&a})})},`TabsContent`));function Nf(e,t){return`${e}-trigger-${t}`}yf(Nf,`makeTriggerId`);function Pf(e,t){return`${e}-content-${t}`}yf(Pf,`makeContentId`);var Ff=Ef,If=Of,Lf=Af,Rf=Mf,zf=Object.defineProperty,Bf=(e,t)=>zf(e,`name`,{value:t,configurable:!0}),[Vf,Hf]=ln(`Tooltip`,[hl]),Uf=hl(),Wf=`TooltipProvider`,Gf=700,Kf=`tooltip.open`,[qf,Jf]=Vf(Wf),Yf=Bf(e=>{let{__scopeTooltip:t,delayDuration:n=Gf,skipDelayDuration:r=300,disableHoverableContent:i=!1,children:a}=e,o=_.useRef(!0),s=_.useRef(!1),c=_.useRef(0);return _.useEffect(()=>{let e=c.current;return()=>window.clearTimeout(e)},[]),(0,U.jsx)(qf,{scope:t,isOpenDelayedRef:o,delayDuration:n,onOpen:_.useCallback(()=>{r<=0||(window.clearTimeout(c.current),o.current=!1)},[r]),onClose:_.useCallback(()=>{r<=0||(window.clearTimeout(c.current),c.current=window.setTimeout(()=>o.current=!0,r))},[r]),isPointerInTransitRef:s,onPointerInTransitChange:_.useCallback(e=>{s.current=e},[]),disableHoverableContent:i,children:a})},`TooltipProvider`),Xf=`Tooltip`,[Zf,Qf]=Vf(Xf),$f=Bf(e=>{let{__scopeTooltip:t,children:n,open:r,defaultOpen:i,onOpenChange:a,disableHoverableContent:o,delayDuration:s}=e,c=Jf(Xf,e.__scopeTooltip),l=Uf(t),[u,d]=_.useState(null),[f,p]=_.useState(void 0),m=ir(),h=_.useRef(0),g=o??c.disableHoverableContent,v=s??c.delayDuration,y=_.useRef(!1),[b,x]=Bn({prop:r,defaultProp:i??!1,onChange:Bf(e=>{e?(c.onOpen(),document.dispatchEvent(new CustomEvent(Kf))):c.onClose(),a?.(e)},`onChange`),caller:Xf}),S=_.useMemo(()=>b?y.current?`delayed-open`:`instant-open`:`closed`,[b]),C=_.useCallback(()=>{window.clearTimeout(h.current),h.current=0,y.current=!1,x(!0)},[x]),w=_.useCallback(()=>{window.clearTimeout(h.current),h.current=0,x(!1)},[x]),T=_.useCallback(()=>{window.clearTimeout(h.current),h.current=window.setTimeout(()=>{y.current=!0,x(!0),h.current=0},v)},[v,x]);_.useEffect(()=>()=>{h.current&&=(window.clearTimeout(h.current),0)},[]);let E=f??m;return(0,U.jsx)(jl,{...l,children:(0,U.jsx)(Zf,{scope:t,contentId:E,setContentId:p,open:b,stateAttribute:S,trigger:u,onTriggerChange:d,onTriggerEnter:_.useCallback(()=>{c.isOpenDelayedRef.current?T():C()},[c.isOpenDelayedRef,T,C]),onTriggerLeave:_.useCallback(()=>{g?w():(window.clearTimeout(h.current),h.current=0)},[w,g]),onOpen:C,onClose:w,disableHoverableContent:g,children:n})})},`Tooltip`),ep=`TooltipTrigger`,tp=_.forwardRef(Bf(function(e,t){let{__scopeTooltip:n,...r}=e,i=Qf(ep,n),a=Jf(ep,n),o=Uf(n),s=Nt(t,_.useRef(null),i.onTriggerChange),c=_.useRef(!1),l=_.useRef(!1),u=_.useCallback(()=>c.current=!1,[]);return _.useEffect(()=>()=>document.removeEventListener(`pointerup`,u),[u]),(0,U.jsx)(Ml,{asChild:!0,...o,children:(0,U.jsx)(W.button,{"aria-describedby":i.open?i.contentId:void 0,"data-state":i.stateAttribute,...r,ref:s,onPointerMove:G(e.onPointerMove,e=>{e.pointerType!==`touch`&&!l.current&&!a.isPointerInTransitRef.current&&(i.onTriggerEnter(),l.current=!0)}),onPointerLeave:G(e.onPointerLeave,()=>{i.onTriggerLeave(),l.current=!1}),onPointerDown:G(e.onPointerDown,()=>{i.open&&i.onClose(),c.current=!0,document.addEventListener(`pointerup`,u,{once:!0})}),onFocus:G(e.onFocus,()=>{c.current||i.onOpen()}),onBlur:G(e.onBlur,i.onClose),onClick:G(e.onClick,i.onClose)})})},`TooltipTrigger`)),np=`TooltipPortal`,[rp,ip]=Vf(np,{forceMount:void 0}),ap=Bf(e=>{let{__scopeTooltip:t,forceMount:n,children:r,container:i}=e,a=Qf(np,t);return(0,U.jsx)(rp,{scope:t,forceMount:n,children:(0,U.jsx)(Jn,{present:n||a.open,children:(0,U.jsx)(ai,{asChild:!0,container:i,children:r})})})},`TooltipPortal`),op=`TooltipContent`,sp=_.forwardRef(Bf(function(e,t){let n=ip(op,e.__scopeTooltip),{forceMount:r=n.forceMount,side:i=`top`,...a}=e,o=Qf(op,e.__scopeTooltip);return(0,U.jsx)(Jn,{present:r||o.open,children:o.disableHoverableContent?(0,U.jsx)(up,{side:i,...a,ref:t}):(0,U.jsx)(cp,{side:i,...a,ref:t})})},`TooltipContent`)),cp=_.forwardRef(Bf(function(e,t){let n=Qf(op,e.__scopeTooltip),r=Jf(op,e.__scopeTooltip),i=_.useRef(null),a=Nt(t,i),[o,s]=_.useState(null),{trigger:c,onClose:l}=n,u=i.current,{onPointerInTransitChange:d}=r,f=_.useCallback(()=>{s(null),d(!1)},[d]),p=_.useCallback((e,t)=>{let n=e.currentTarget,r={x:e.clientX,y:e.clientY},i=pp(r,fp(r,n.getBoundingClientRect())),a=mp(t.getBoundingClientRect()),o=gp([...i,...a]);s(o),d(!0)},[d]);return _.useEffect(()=>()=>f(),[f]),_.useEffect(()=>{if(c&&u){let e=Bf(e=>p(e,u),`handleTriggerLeave`),t=Bf(e=>p(e,c),`handleContentLeave`);return c.addEventListener(`pointerleave`,e),u.addEventListener(`pointerleave`,t),()=>{c.removeEventListener(`pointerleave`,e),u.removeEventListener(`pointerleave`,t)}}},[c,u,p,f]),_.useEffect(()=>{if(o){let e=Bf(e=>{let t=e.target,n={x:e.clientX,y:e.clientY},r=c?.contains(t)||u?.contains(t),i=!hp(n,o);r?f():i&&(f(),l())},`handleTrackPointerGrace`);return document.addEventListener(`pointermove`,e),()=>document.removeEventListener(`pointermove`,e)}},[c,u,o,l,f]),(0,U.jsx)(up,{...e,ref:a})},`TooltipContentHoverable`)),lp=Bt(`TooltipContent`),up=_.forwardRef(Bf(function(e,t){let{__scopeTooltip:n,children:r,"aria-label":i,id:a,onEscapeKeyDown:o,onPointerDownOutside:s,...c}=e,l=Qf(op,n),u=Uf(n),{onClose:d}=l;_.useEffect(()=>(document.addEventListener(Kf,d),()=>document.removeEventListener(Kf,d)),[d]),_.useEffect(()=>{if(l.trigger){let e=Bf(e=>{e.target instanceof Node&&e.target.contains(l.trigger)&&d()},`handleScroll`);return window.addEventListener(`scroll`,e,{capture:!0}),()=>window.removeEventListener(`scroll`,e,{capture:!0})}},[l.trigger,d]);let{setContentId:f}=l;return jn(()=>(f(a),()=>{f(void 0)}),[a,f]),(0,U.jsx)(Pr,{asChild:!0,disableOutsidePointerEvents:!1,onEscapeKeyDown:o,onPointerDownOutside:s,onFocusOutside:e=>e.preventDefault(),onDismiss:d,children:(0,U.jsxs)(Nl,{"data-state":l.stateAttribute,role:i?void 0:`tooltip`,id:i?void 0:l.contentId,...u,...c,ref:t,style:{...c.style,"--radix-tooltip-content-transform-origin":`var(--radix-popper-transform-origin)`,"--radix-tooltip-content-available-width":`var(--radix-popper-available-width)`,"--radix-tooltip-content-available-height":`var(--radix-popper-available-height)`,"--radix-tooltip-trigger-width":`var(--radix-popper-anchor-width)`,"--radix-tooltip-trigger-height":`var(--radix-popper-anchor-height)`},children:[(0,U.jsx)(lp,{children:r}),i?(0,U.jsx)(an,{id:l.contentId,role:`tooltip`,children:i}):null]})})},`TooltipContentImpl`)),dp=_.forwardRef(Bf(function(e,t){let{__scopeTooltip:n,...r}=e,i=Uf(n);return(0,U.jsx)(Pl,{...i,...r,ref:t})},`TooltipArrow`));function fp(e,t){let n=Math.abs(t.top-e.y),r=Math.abs(t.bottom-e.y),i=Math.abs(t.right-e.x),a=Math.abs(t.left-e.x);switch(Math.min(n,r,i,a)){case a:return`left`;case i:return`right`;case n:return`top`;case r:return`bottom`;default:throw Error(`unreachable`)}}Bf(fp,`getExitSideFromRect`);function pp(e,t,n=5){let r=[];switch(t){case`top`:r.push({x:e.x-n,y:e.y+n},{x:e.x+n,y:e.y+n});break;case`bottom`:r.push({x:e.x-n,y:e.y-n},{x:e.x+n,y:e.y-n});break;case`left`:r.push({x:e.x+n,y:e.y-n},{x:e.x+n,y:e.y+n});break;case`right`:r.push({x:e.x-n,y:e.y-n},{x:e.x-n,y:e.y+n})}return r}Bf(pp,`getPaddedExitPoints`);function mp(e){let{top:t,right:n,bottom:r,left:i}=e;return[{x:i,y:t},{x:n,y:t},{x:n,y:r},{x:i,y:r}]}Bf(mp,`getPointsFromRect`);function hp(e,t){let{x:n,y:r}=e,i=!1;for(let e=0,a=t.length-1;er!=d>r&&n<(u-c)*(r-l)/(d-l)+c&&(i=!i)}return i}Bf(hp,`isPointInPolygon`);function gp(e){let t=e.slice();return t.sort((e,t)=>e.xt.x?1:e.yt.y)),_p(t)}Bf(gp,`getHull`);function _p(e){if(e.length<=1)return e.slice();let t=[];for(let n=0;n=2;){let e=t[t.length-1],n=t[t.length-2];if((e.x-n.x)*(r.y-n.y)>=(e.y-n.y)*(r.x-n.x))t.pop();else break}t.push(r)}t.pop();let n=[];for(let t=e.length-1;t>=0;t--){let r=e[t];for(;n.length>=2;){let e=n[n.length-1],t=n[n.length-2];if((e.x-t.x)*(r.y-t.y)>=(e.y-t.y)*(r.x-t.x))n.pop();else break}n.push(r)}return n.pop(),t.length===1&&n.length===1&&t[0].x===n[0].x&&t[0].y===n[0].y?t:t.concat(n)}Bf(_p,`getHullPresorted`);var vp=Yf,yp=$f,bp=tp,xp=ap,Sp=sp,Cp=dp,wp=Ot(`group/button inline-flex shrink-0 items-center justify-center rounded-[6px] border border-transparent bg-clip-padding text-[13px] font-medium leading-[18px] whitespace-nowrap transition-colors duration-150 outline-none select-none focus-visible:outline-2 focus-visible:outline-[var(--app-focus-ring)] focus-visible:outline-offset-2 motion-reduce:transition-none disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-[var(--app-critical-foreground)] [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,{variants:{variant:{default:`border-primary bg-primary text-primary-foreground hover:border-[var(--app-accent-hover)] hover:bg-[var(--app-accent-hover)] active:border-[var(--app-accent-pressed)] active:bg-[var(--app-accent-pressed)]`,outline:`border-border bg-card text-foreground hover:bg-secondary aria-expanded:bg-secondary`,secondary:`border-border bg-secondary text-secondary-foreground hover:border-[var(--app-border-strong)] aria-expanded:border-[var(--app-border-strong)]`,ghost:`text-foreground hover:bg-secondary aria-expanded:bg-secondary`,destructive:`border-[var(--app-critical-foreground)] bg-[var(--app-critical-tint)] text-[var(--app-critical-foreground)]`,link:`text-primary underline underline-offset-4`},size:{default:`h-10 gap-1.5 px-3 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2`,lg:`h-10 gap-1.5 px-3 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2`,icon:`size-10`}},defaultVariants:{variant:`default`,size:`default`}});function Tp({className:e,variant:t=`default`,size:n=`default`,asChild:r=!1,...i}){let a=r?Rt:`button`;return(0,U.jsx)(a,{"data-slot":`button`,"data-variant":t,"data-size":n,className:H(wp({variant:t,size:n,className:e})),...i})}var Ep=Ot(`group/alert relative grid w-full gap-1 rounded-[8px] border p-3 text-left text-[13px] leading-[18px] has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4`,{variants:{variant:{default:`border-border bg-secondary text-foreground`,destructive:`border-[var(--app-critical-foreground)] bg-[var(--app-critical-tint)] text-[var(--app-critical-foreground)] *:data-[slot=alert-description]:text-[var(--app-critical-foreground)] *:[svg]:text-current`}},defaultVariants:{variant:`default`}});function Dp({className:e,variant:t,...n}){return(0,U.jsx)(`div`,{"data-slot":`alert`,role:`alert`,className:H(Ep({variant:t}),e),...n})}function Op({className:e,...t}){return(0,U.jsx)(`div`,{"data-slot":`alert-title`,className:H(`font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground`,e),...t})}function kp({className:e,...t}){return(0,U.jsx)(`div`,{"data-slot":`alert-description`,className:H(`text-[13px] leading-[18px] text-muted-foreground [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4`,e),...t})}function Ap({className:e,...t}){return(0,U.jsx)(Wd,{"data-slot":`label`,className:H(`flex items-center gap-2 text-[13px] leading-[18px] font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50`,e),...t})}function jp({className:e,...t}){return(0,U.jsx)(`div`,{"data-slot":`field-group`,className:H(`group/field-group flex w-full flex-col gap-4`,e),...t})}var Mp=Ot(`group/field flex w-full gap-2 data-[invalid=true]:text-destructive`,{variants:{orientation:{vertical:`flex-col *:w-full [&>.sr-only]:w-auto`,horizontal:`flex-row items-center has-[>[data-slot=field-content]]:items-start *:data-[slot=field-label]:flex-auto has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px`,responsive:`flex-col *:w-full @md/field-group:flex-row @md/field-group:items-center @md/field-group:*:w-auto @md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:*:data-[slot=field-label]:flex-auto [&>.sr-only]:w-auto @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px`}},defaultVariants:{orientation:`vertical`}});function Np({className:e,orientation:t=`vertical`,...n}){return(0,U.jsx)(`div`,{role:`group`,"data-slot":`field`,"data-orientation":t,className:H(Mp({orientation:t}),e),...n})}function Pp({className:e,...t}){return(0,U.jsx)(`div`,{"data-slot":`field-content`,className:H(`group/field-content flex flex-1 flex-col gap-0.5 leading-snug`,e),...t})}function Fp({className:e,...t}){return(0,U.jsx)(Ap,{"data-slot":`field-label`,className:H(`group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50`,e),...t})}function Ip({className:e,...t}){return(0,U.jsx)(`p`,{"data-slot":`field-description`,className:H(`m-0 text-left text-[13px] leading-[18px] font-normal text-muted-foreground`,e),...t})}function Lp({className:e,children:t,errors:n,...r}){let i=(0,_.useMemo)(()=>{if(t)return t;if(!n?.length)return null;let e=[...new Map(n.map(e=>[e?.message,e])).values()];return e?.length==1?e[0]?.message:(0,U.jsx)(`ul`,{className:`ml-4 flex list-disc flex-col gap-1`,children:e.map((e,t)=>e?.message&&(0,U.jsx)(`li`,{children:e.message},t))})},[t,n]);return i?(0,U.jsx)(`div`,{role:`alert`,"data-slot":`field-error`,className:H(`text-[13px] leading-[18px] font-normal text-destructive`,e),...r,children:i}):null}function Rp({className:e,type:t,...n}){return(0,U.jsx)(`input`,{type:t,"data-slot":`input`,className:H(`h-10 w-full min-w-0 rounded-[6px] border border-input bg-card px-3 text-[14px] leading-5 text-foreground transition-colors outline-none placeholder:text-muted-foreground focus-visible:outline-2 focus-visible:outline-[var(--app-focus-ring)] focus-visible:outline-offset-2 disabled:cursor-not-allowed disabled:bg-secondary disabled:opacity-70 aria-invalid:border-[var(--app-critical-foreground)]`,e),...n})}function zp({className:e,...t}){return(0,U.jsx)(`div`,{"data-slot":`input-group`,role:`group`,className:H(`group/input-group relative flex h-10 w-full min-w-0 items-center rounded-[6px] border border-input bg-card transition-colors has-disabled:bg-secondary has-disabled:opacity-70 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot][aria-invalid=true]]:border-[var(--app-critical-foreground)]`,e),...t})}var Bp=Ot(`flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4`,{variants:{align:{"inline-start":`order-first pl-2 has-[>button]:ml-[-0.3rem] has-[>kbd]:ml-[-0.15rem]`,"inline-end":`order-last pr-2 has-[>button]:mr-[-0.3rem] has-[>kbd]:mr-[-0.15rem]`,"block-start":`order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2`,"block-end":`order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2`}},defaultVariants:{align:`inline-start`}});function Vp({className:e,align:t=`inline-start`,...n}){return(0,U.jsx)(`div`,{role:`group`,"data-slot":`input-group-addon`,"data-align":t,className:H(Bp({align:t}),e),onClick:e=>{e.target instanceof Element&&e.target.closest(`button`)||e.currentTarget.parentElement?.querySelector(`input`)?.focus()},...n})}function Hp({className:e,type:t=`button`,variant:n=`ghost`,size:r=`default`,...i}){return(0,U.jsx)(Tp,{type:t,"data-size":r,variant:n,size:r,className:H(`h-full rounded-[4px] px-3`,e),...i})}function Up({className:e,...t}){return(0,U.jsx)(Rp,{"data-slot":`input-group-control`,className:H(`h-auto min-h-0 flex-1 rounded-none border-0 bg-transparent px-3 focus-visible:outline-2 focus-visible:outline-[var(--app-focus-ring)] focus-visible:outline-offset-2 disabled:bg-transparent`,e),...t})}var Wp=`••••••••`;function Gp({inputRef:e,error:t,savedTokenError:n=null,usingSavedToken:r,isValidating:i,locked:a=!1,onUseDifferentToken:o}){let[s,c]=(0,_.useState)(!1),l=r||i||a,u=[t?`token-error`:null,n?`saved-token-error`:null,r&&!n?`saved-token-status`:null].filter(Boolean).join(` `)||void 0;return(0,U.jsxs)(Np,{"data-invalid":!!t,children:[(0,U.jsx)(Fp,{htmlFor:`access-token`,children:`Access token`}),(0,U.jsxs)(zp,{children:[(0,U.jsx)(Up,{ref:e,id:`access-token`,type:s&&!l?`text`:`password`,disabled:l,placeholder:r||a?Wp:void 0,autoComplete:`off`,"aria-describedby":u,"aria-invalid":t?!0:void 0,"aria-required":!r&&!a}),!r&&!a?(0,U.jsx)(Vp,{align:`inline-end`,children:(0,U.jsx)(Hp,{"aria-pressed":s,disabled:i,onClick:()=>c(e=>!e),children:s?`Hide token`:`Show token`})}):null]}),r?(0,U.jsxs)(Dp,{id:n?`saved-token-error`:`saved-token-status`,role:n?`alert`:`note`,variant:n?`destructive`:`default`,children:[(0,U.jsx)(Op,{children:n?`Saved token needs replacement`:`Saved token`}),(0,U.jsx)(kp,{children:n?(0,U.jsx)(`p`,{children:n}):`This token is stored in the local token.json file for the selected cluster.`}),(0,U.jsx)(Tp,{type:`button`,variant:`link`,disabled:i,onClick:o,children:n?`Enter replacement token`:`Use a different token`})]}):null,(0,U.jsx)(Lp,{id:`token-error`,children:t})]})}var Kp=1,qp=.9,Jp=.8,Yp=.17,Xp=.1,Zp=.999,Qp=.9999,$p=.99,em=/[\\\/_+.#"@\[\(\{&]/,tm=/[\\\/_+.#"@\[\(\{&]/g,nm=/[\s-]/,rm=/[\s-]/g;function im(e,t,n,r,i,a,o){if(a===t.length)return i===e.length?Kp:$p;var s=`${i},${a}`;if(o[s]!==void 0)return o[s];for(var c=r.charAt(a),l=n.indexOf(c,i),u=0,d,f,p,m;l>=0;)d=im(e,t,n,r,l+1,a+1,o),d>u&&(l===i?d*=Kp:em.test(e.charAt(l-1))?(d*=Jp,p=e.slice(i,l-1).match(tm),p&&i>0&&(d*=Zp**+p.length)):nm.test(e.charAt(l-1))?(d*=qp,m=e.slice(i,l-1).match(rm),m&&i>0&&(d*=Zp**+m.length)):(d*=Yp,i>0&&(d*=Zp**+(l-i))),e.charAt(l)!==t.charAt(a)&&(d*=Qp)),(dd&&(d=f*Xp)),d>u&&(u=d),l=n.indexOf(c,l+1);return o[s]=u,u}function am(e){return e.toLowerCase().replace(rm,` `)}function om(e,t,n){return e=n&&n.length>0?`${e+` `+n.join(` `)}`:e,im(e,t,am(e),am(t),0,0,{})}var sm=`[cmdk-group=""]`,cm=`[cmdk-group-items=""]`,lm=`[cmdk-group-heading=""]`,um=`[cmdk-item=""]`,dm=`${um}:not([aria-disabled="true"])`,fm=`cmdk-item-select`,pm=`data-value`,mm=(e,t,n)=>om(e,t,n),hm=_.createContext(void 0),gm=()=>_.useContext(hm),_m=_.createContext(void 0),vm=()=>_.useContext(_m),ym=_.createContext(void 0),bm=_.forwardRef((e,t)=>{let n=Pm(()=>({search:``,value:e.value??e.defaultValue??``,selectedItemId:void 0,filtered:{count:0,items:new Map,groups:new Set}})),r=Pm(()=>new Set),i=Pm(()=>new Map),a=Pm(()=>new Map),o=Pm(()=>new Set),s=Mm(e),{label:c,children:l,value:u,onValueChange:d,filter:f,shouldFilter:p,loop:m,disablePointerSelection:h=!1,vimBindings:g=!0,...v}=e,y=ir(),b=ir(),x=ir(),S=_.useRef(null),C=Lm();Nm(()=>{if(u!==void 0){let e=u.trim();n.current.value=e,w.emit()}},[u]),Nm(()=>{C(6,ee)},[]);let w=_.useMemo(()=>({subscribe:e=>(o.current.add(e),()=>o.current.delete(e)),snapshot:()=>n.current,setState:(e,t,r)=>{var i,a,o;if(!Object.is(n.current[e],t)){if(n.current[e]=t,e===`search`)k(),D(),C(1,O);else if(e===`value`){if(document.activeElement.hasAttribute(`cmdk-input`)||document.activeElement.hasAttribute(`cmdk-root`)){let e=document.getElementById(x);e?e.focus():(i=document.getElementById(y))==null||i.focus()}if(C(7,()=>{n.current.selectedItemId=A()?.id,w.emit()}),r||C(5,ee),s.current?.value!==void 0){let e=t??``;(o=(a=s.current).onValueChange)==null||o.call(a,e);return}}w.emit()}},emit:()=>{o.current.forEach(e=>e())}}),[]),T=_.useMemo(()=>({value:(e,t,r)=>{t!==a.current.get(e)?.value&&(a.current.set(e,{value:t,keywords:r}),n.current.filtered.items.set(e,E(t,r)),C(2,()=>{D(),w.emit()}))},item:(e,t)=>(r.current.add(e),t&&(i.current.has(t)?i.current.get(t).add(e):i.current.set(t,new Set([e]))),C(3,()=>{k(),D(),n.current.value||O(),w.emit()}),()=>{a.current.delete(e),r.current.delete(e),n.current.filtered.items.delete(e);let t=A();C(4,()=>{k(),t?.getAttribute(`id`)===e&&O(),w.emit()})}),group:e=>(i.current.has(e)||i.current.set(e,new Set),()=>{a.current.delete(e),i.current.delete(e)}),filter:()=>s.current.shouldFilter,label:c||e[`aria-label`],getDisablePointerSelection:()=>s.current.disablePointerSelection,listId:y,inputId:x,labelId:b,listInnerRef:S}),[]);function E(e,t){let r=s.current?.filter??mm;return e?r(e,n.current.search,t):0}function D(){if(!n.current.search||s.current.shouldFilter===!1)return;let e=n.current.filtered.items,t=[];n.current.filtered.groups.forEach(n=>{let r=i.current.get(n),a=0;r.forEach(t=>{let n=e.get(t);a=Math.max(n,a)}),t.push([n,a])});let r=S.current;j().sort((t,n)=>{let r=t.getAttribute(`id`),i=n.getAttribute(`id`);return(e.get(i)??0)-(e.get(r)??0)}).forEach(e=>{let t=e.closest(cm);t?t.appendChild(e.parentElement===t?e:e.closest(`${cm} > *`)):r.appendChild(e.parentElement===r?e:e.closest(`${cm} > *`))}),t.sort((e,t)=>t[1]-e[1]).forEach(e=>{let t=S.current?.querySelector(`${sm}[${pm}="${encodeURIComponent(e[0])}"]`);t?.parentElement.appendChild(t)})}function O(){let e=j().find(e=>e.getAttribute(`aria-disabled`)!==`true`)?.getAttribute(pm);w.setState(`value`,e||void 0)}function k(){if(!n.current.search||s.current.shouldFilter===!1){n.current.filtered.count=r.current.size;return}n.current.filtered.groups=new Set;let e=0;for(let t of r.current){let r=E(a.current.get(t)?.value??``,a.current.get(t)?.keywords??[]);n.current.filtered.items.set(t,r),r>0&&e++}for(let[e,t]of i.current)for(let r of t)if(n.current.filtered.items.get(r)>0){n.current.filtered.groups.add(e);break}n.current.filtered.count=e}function ee(){var e;let t=A();t&&(t.parentElement?.firstChild===t&&((e=t.closest(sm)?.querySelector(lm))==null||e.scrollIntoView({block:`nearest`})),t.scrollIntoView({block:`nearest`}))}function A(){return S.current?.querySelector(`${um}[aria-selected="true"]`)}function j(){return Array.from(S.current?.querySelectorAll(dm)||[])}function M(e){let t=j()[e];t&&w.setState(`value`,t.getAttribute(pm))}function N(e){var t;let n=A(),r=j(),i=r.findIndex(e=>e===n),a=r[i+e];(t=s.current)!=null&&t.loop&&(a=i+e<0?r[r.length-1]:i+e===r.length?r[0]:r[i+e]),a&&w.setState(`value`,a.getAttribute(pm))}function P(e){let t=A()?.closest(sm),n;for(;t&&!n;)t=e>0?Am(t,sm):jm(t,sm),n=t?.querySelector(dm);n?w.setState(`value`,n.getAttribute(pm)):N(e)}let F=()=>M(j().length-1),I=e=>{e.preventDefault(),e.metaKey?F():e.altKey?P(1):N(1)},te=e=>{e.preventDefault(),e.metaKey?M(0):e.altKey?P(-1):N(-1)};return _.createElement(W.div,{ref:t,tabIndex:-1,...v,"cmdk-root":``,onKeyDown:e=>{var t;(t=v.onKeyDown)==null||t.call(v,e);let n=e.nativeEvent.isComposing||e.keyCode===229;if(!(e.defaultPrevented||n))switch(e.key){case`n`:case`j`:g&&e.ctrlKey&&I(e);break;case`ArrowDown`:I(e);break;case`p`:case`k`:g&&e.ctrlKey&&te(e);break;case`ArrowUp`:te(e);break;case`Home`:e.preventDefault(),M(0);break;case`End`:e.preventDefault(),F();break;case`Enter`:{e.preventDefault();let t=A();if(t){let e=new Event(fm);t.dispatchEvent(e)}}}}},_.createElement(`label`,{"cmdk-label":``,htmlFor:T.inputId,id:T.labelId,style:Bm},c),zm(e,e=>_.createElement(_m.Provider,{value:w},_.createElement(hm.Provider,{value:T},e))))}),xm=_.forwardRef((e,t)=>{let n=ir(),r=_.useRef(null),i=_.useContext(ym),a=gm(),o=Mm(e),s=o.current?.forceMount??i?.forceMount;Nm(()=>{if(!s)return a.item(n,i?.id)},[s]);let c=Im(n,r,[e.value,e.children,r],e.keywords),l=vm(),u=Fm(e=>e.value&&e.value===c.current),d=Fm(e=>s||a.filter()===!1?!0:!e.search||e.filtered.items.get(n)>0);_.useEffect(()=>{let t=r.current;if(!(!t||e.disabled))return t.addEventListener(fm,f),()=>t.removeEventListener(fm,f)},[d,e.onSelect,e.disabled]);function f(){var e,t;p(),(t=(e=o.current).onSelect)==null||t.call(e,c.current)}function p(){l.setState(`value`,c.current,!0)}if(!d)return null;let{disabled:m,value:h,onSelect:g,forceMount:v,keywords:y,...b}=e;return _.createElement(W.div,{ref:Mt(r,t),...b,id:n,"cmdk-item":``,role:`option`,"aria-disabled":!!m,"aria-selected":!!u,"data-disabled":!!m,"data-selected":!!u,onPointerMove:m||a.getDisablePointerSelection()?void 0:p,onClick:m?void 0:f},e.children)}),Sm=_.forwardRef((e,t)=>{let{heading:n,children:r,forceMount:i,...a}=e,o=ir(),s=_.useRef(null),c=_.useRef(null),l=ir(),u=gm(),d=Fm(e=>i||u.filter()===!1?!0:!e.search||e.filtered.groups.has(o));Nm(()=>u.group(o),[]),Im(o,s,[e.value,e.heading,c]);let f=_.useMemo(()=>({id:o,forceMount:i}),[i]);return _.createElement(W.div,{ref:Mt(s,t),...a,"cmdk-group":``,role:`presentation`,hidden:!d||void 0},n&&_.createElement(`div`,{ref:c,"cmdk-group-heading":``,"aria-hidden":!0,id:l},n),zm(e,e=>_.createElement(`div`,{"cmdk-group-items":``,role:`group`,"aria-labelledby":n?l:void 0},_.createElement(ym.Provider,{value:f},e))))}),Cm=_.forwardRef((e,t)=>{let{alwaysRender:n,...r}=e,i=_.useRef(null),a=Fm(e=>!e.search);return!n&&!a?null:_.createElement(W.div,{ref:Mt(i,t),...r,"cmdk-separator":``,role:`separator`})}),wm=_.forwardRef((e,t)=>{let{onValueChange:n,...r}=e,i=e.value!=null,a=vm(),o=Fm(e=>e.search),s=Fm(e=>e.selectedItemId),c=gm();return _.useEffect(()=>{e.value!=null&&a.setState(`search`,e.value)},[e.value]),_.createElement(W.input,{ref:t,...r,"cmdk-input":``,autoComplete:`off`,autoCorrect:`off`,spellCheck:!1,"aria-autocomplete":`list`,role:`combobox`,"aria-expanded":!0,"aria-controls":c.listId,"aria-labelledby":c.labelId,"aria-activedescendant":s,id:c.inputId,type:`text`,value:i?e.value:o,onChange:e=>{i||a.setState(`search`,e.target.value),n?.(e.target.value)}})}),Tm=_.forwardRef((e,t)=>{let{children:n,label:r=`Suggestions`,...i}=e,a=_.useRef(null),o=_.useRef(null),s=Fm(e=>e.selectedItemId),c=gm();return _.useEffect(()=>{if(o.current&&a.current){let e=o.current,t=a.current,n,r=new ResizeObserver(()=>{n=requestAnimationFrame(()=>{let n=e.offsetHeight;t.style.setProperty(`--cmdk-list-height`,n.toFixed(1)+`px`)})});return r.observe(e),()=>{cancelAnimationFrame(n),r.unobserve(e)}}},[]),_.createElement(W.div,{ref:Mt(a,t),...i,"cmdk-list":``,role:`listbox`,tabIndex:-1,"aria-activedescendant":s,"aria-label":r,id:c.listId},zm(e,e=>_.createElement(`div`,{ref:Mt(o,c.listInnerRef),"cmdk-list-sizer":``},e)))}),Em=_.forwardRef((e,t)=>{let{open:n,onOpenChange:r,overlayClassName:i,contentClassName:a,container:o,...s}=e;return _.createElement(La,{open:n,onOpenChange:r},_.createElement(Ua,{container:o},_.createElement(Ga,{"cmdk-overlay":``,className:i}),_.createElement(Ya,{"aria-label":e.label,"cmdk-dialog":``,className:a},_.createElement(bm,{ref:t,...s}))))}),Dm=_.forwardRef((e,t)=>Fm(e=>e.filtered.count===0)?_.createElement(W.div,{ref:t,...e,"cmdk-empty":``,role:`presentation`}):null),Om=_.forwardRef((e,t)=>{let{progress:n,children:r,label:i=`Loading...`,...a}=e;return _.createElement(W.div,{ref:t,...a,"cmdk-loading":``,role:`progressbar`,"aria-valuenow":n,"aria-valuemin":0,"aria-valuemax":100,"aria-label":i},zm(e,e=>_.createElement(`div`,{"aria-hidden":!0},e)))}),km=Object.assign(bm,{List:Tm,Item:xm,Input:wm,Group:Sm,Separator:Cm,Dialog:Em,Empty:Dm,Loading:Om});function Am(e,t){let n=e.nextElementSibling;for(;n;){if(n.matches(t))return n;n=n.nextElementSibling}}function jm(e,t){let n=e.previousElementSibling;for(;n;){if(n.matches(t))return n;n=n.previousElementSibling}}function Mm(e){let t=_.useRef(e);return Nm(()=>{t.current=e}),t}var Nm=typeof window>`u`?_.useEffect:_.useLayoutEffect;function Pm(e){let t=_.useRef();return t.current===void 0&&(t.current=e()),t}function Fm(e){let t=vm(),n=()=>e(t.snapshot());return _.useSyncExternalStore(t.subscribe,n,n)}function Im(e,t,n,r=[]){let i=_.useRef(),a=gm();return Nm(()=>{var o;let s=(()=>{for(let e of n){if(typeof e==`string`)return e.trim();if(typeof e==`object`&&`current`in e)return e.current?e.current.textContent?.trim():i.current}})(),c=r.map(e=>e.trim());a.value(e,s,c),(o=t.current)==null||o.setAttribute(pm,s),i.current=s}),i}var Lm=()=>{let[e,t]=_.useState(),n=Pm(()=>new Map);return Nm(()=>{n.current.forEach(e=>e()),n.current=new Map},[e]),(e,r)=>{n.current.set(e,r),t({})}};function Rm(e){let t=e.type;return typeof t==`function`?t(e.props):`render`in t?t.render(e.props):e}function zm({asChild:e,children:t},n){return e&&_.isValidElement(t)?_.cloneElement(Rm(t),{ref:t.ref},n(t.props.children)):n(t)}var Bm={position:`absolute`,width:`1px`,height:`1px`,padding:`0`,margin:`-1px`,overflow:`hidden`,clip:`rect(0, 0, 0, 0)`,whiteSpace:`nowrap`,borderWidth:`0`};function Vm({className:e,...t}){return(0,U.jsx)(km,{"data-slot":`command`,className:H(`flex size-full flex-col overflow-hidden bg-popover text-popover-foreground`,e),...t})}function Hm({className:e,...t}){return(0,U.jsx)(km.Input,{"data-slot":`command-input`,className:H(`h-10 w-full border-b border-border bg-card px-3 text-[14px] leading-5 outline-none placeholder:text-muted-foreground focus-visible:outline-2 focus-visible:outline-[var(--app-focus-ring)] focus-visible:outline-offset-[-2px] disabled:cursor-not-allowed disabled:bg-secondary disabled:opacity-70`,e),...t})}function Um({className:e,...t}){return(0,U.jsx)(km.List,{"data-slot":`command-list`,className:H(`max-h-60 scroll-py-1 overflow-x-hidden overflow-y-auto outline-none`,e),...t})}function Wm({className:e,...t}){return(0,U.jsx)(km.Empty,{"data-slot":`command-empty`,className:H(`p-3 text-center text-[13px] text-muted-foreground`,e),...t})}function Gm({className:e,...t}){return(0,U.jsx)(km.Group,{"data-slot":`command-group`,className:H(`overflow-hidden p-1 text-foreground`,e),...t})}function Km({className:e,...t}){return(0,U.jsx)(km.Item,{"data-slot":`command-item`,className:H(`grid min-h-10 cursor-default gap-0.5 rounded-[6px] px-2 py-1 text-[13px] leading-[18px] outline-none select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-selected:bg-secondary data-selected:text-foreground [&>span:first-child]:font-medium [&>span:last-child]:overflow-wrap-anywhere [&>span:last-child]:text-[12px] [&>span:last-child]:leading-4 [&>span:last-child]:text-muted-foreground`,e),...t})}function qm({...e}){return(0,U.jsx)(mf,{"data-slot":`popover`,...e})}function Jm({...e}){return(0,U.jsx)(hf,{"data-slot":`popover-trigger`,...e})}function Ym({className:e,align:t=`start`,sideOffset:n=4,...r}){return(0,U.jsx)(gf,{children:(0,U.jsx)(_f,{"data-slot":`popover-content`,align:t,sideOffset:n,className:H(`z-50 flex w-(--radix-popover-trigger-width) flex-col rounded-[8px] border border-border bg-popover p-1 text-sm text-popover-foreground`,e),...r})})}var Xm=[{name:`US-1`,origin:`https://app1-apigw.central.arubanetworks.com`},{name:`US-2`,origin:`https://apigw-prod2.central.arubanetworks.com`},{name:`US-East1`,origin:`https://apigw-us-east-1.central.arubanetworks.com`},{name:`US-West4`,origin:`https://apigw-uswest4.central.arubanetworks.com`},{name:`US-West5`,origin:`https://apigw-uswest5.central.arubanetworks.com`},{name:`EU-1`,origin:`https://eu-apigw.central.arubanetworks.com`},{name:`EU-Central2`,origin:`https://apigw-eucentral2.central.arubanetworks.com`},{name:`EU-Central3`,origin:`https://apigw-eucentral3.central.arubanetworks.com`},{name:`Canada-1`,origin:`https://apigw-ca.central.arubanetworks.com`},{name:`China-1`,origin:`https://apigw.central.arubanetworks.com.cn`},{name:`APAC-1`,origin:`https://api-ap.central.arubanetworks.com`},{name:`APAC-EAST1`,origin:`https://apigw-apaceast.central.arubanetworks.com`},{name:`APAC-SOUTH1`,origin:`https://apigw-apacsouth.central.arubanetworks.com`},{name:`UAE-NORTH1`,origin:`https://apigw-uaenorth1.central.arubanetworks.com`},{name:`Internal`,origin:`https://internal-apigw.central.arubanetworks.com`}],Zm=`Enabled alerts could not be retrieved. Check the connection and try again.`,Qm=`Enabled alerts could not be retrieved. Try again.`,$m=`Another extraction is already running. Wait for it to finish or cancel it, then try again.`,eh={invalid_access:`Enter a new access token and start another extraction.`,rate_limited:`Wait a few minutes, then retry this extraction.`,service_unavailable:`Classic Central is temporarily unavailable. Retry this extraction.`,request_rejected:`Check the selected cluster and access token, then start a new extraction.`,transport:`Check the network connection, then retry this extraction.`},th={kind:`credentials`},nh={validate:async()=>({outcome:`unavailable`})},rh={validate:async()=>({outcome:`valid`})};function ih(e,t){return+!!e.toLocaleLowerCase().includes(t.toLocaleLowerCase())}function ah({selectedCluster:e,error:t,disabled:n,triggerRef:r,onSelected:i,onSearchChanged:a}){let[o,s]=(0,_.useState)(!1),c=[e?`cluster-origin`:null,t?`cluster-error`:null].filter(Boolean).join(` `)||void 0;return(0,U.jsxs)(Np,{"data-invalid":!!t,children:[(0,U.jsx)(Fp,{htmlFor:`cluster-combobox`,children:`Cluster`}),(0,U.jsxs)(qm,{open:o,onOpenChange:s,children:[(0,U.jsx)(Jm,{asChild:!0,children:(0,U.jsx)(Tp,{type:`button`,ref:r,id:`cluster-combobox`,role:`combobox`,variant:`outline`,className:`w-full justify-start`,disabled:n,"aria-expanded":o,"aria-required":`true`,"aria-invalid":t?!0:void 0,"aria-describedby":c,children:e?.name??`Select your account's cluster`})}),(0,U.jsx)(Ym,{children:(0,U.jsxs)(Vm,{filter:ih,children:[(0,U.jsx)(Hm,{autoFocus:!0,placeholder:`Search account clusters`,onValueChange:a}),(0,U.jsxs)(Um,{children:[(0,U.jsx)(Wm,{children:`No account clusters match.`}),(0,U.jsx)(Gm,{children:Xm.map(e=>(0,U.jsxs)(Km,{value:`${e.name} ${e.origin}`,onSelect:()=>{i(e),s(!1)},children:[(0,U.jsx)(`span`,{children:e.name}),(0,U.jsx)(`span`,{children:e.origin})]},e.name))})]})]})})]}),e?(0,U.jsx)(Ip,{id:`cluster-origin`,className:`cluster-origin`,children:e.origin}):null,(0,U.jsx)(Lp,{id:`cluster-error`,children:t})]})}function oh({...e}){return(0,U.jsx)(So,{"data-slot":`alert-dialog`,...e})}function sh({...e}){return(0,U.jsx)(Co,{"data-slot":`alert-dialog-trigger`,...e})}function ch({...e}){return(0,U.jsx)(wo,{"data-slot":`alert-dialog-portal`,...e})}function lh({className:e,...t}){return(0,U.jsx)(To,{"data-slot":`alert-dialog-overlay`,className:H(`fixed inset-0 z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0`,e),...t})}function uh({className:e,size:t=`default`,...n}){return(0,U.jsxs)(ch,{children:[(0,U.jsx)(lh,{}),(0,U.jsx)(Eo,{"data-slot":`alert-dialog-content`,"data-size":t,className:H(`group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95`,e),...n})]})}function dh({className:e,...t}){return(0,U.jsx)(`div`,{"data-slot":`alert-dialog-header`,className:H(`grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]`,e),...t})}function fh({className:e,...t}){return(0,U.jsx)(`div`,{"data-slot":`alert-dialog-footer`,className:H(`-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end`,e),...t})}function ph({className:e,...t}){return(0,U.jsx)(ko,{"data-slot":`alert-dialog-title`,className:H(`text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2`,e),...t})}function mh({className:e,...t}){return(0,U.jsx)(Ao,{"data-slot":`alert-dialog-description`,className:H(`text-sm text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground`,e),...t})}function hh({className:e,variant:t=`default`,size:n=`default`,...r}){return(0,U.jsx)(Tp,{variant:t,size:n,asChild:!0,children:(0,U.jsx)(Do,{"data-slot":`alert-dialog-action`,className:H(e),...r})})}function gh({className:e,variant:t=`outline`,size:n=`default`,...r}){return(0,U.jsx)(Tp,{variant:t,size:n,asChild:!0,children:(0,U.jsx)(Oo,{"data-slot":`alert-dialog-cancel`,className:H(e),...r})})}function _h(e){return(0,U.jsx)(`svg`,{"aria-hidden":`true`,fill:`none`,viewBox:`0 0 16 16`,...e,children:(0,U.jsx)(`path`,{d:`m3.5 8 3 3 6-6`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`1.5`})})}function vh({className:e,...t}){return(0,U.jsx)(Wo,{"data-slot":`checkbox`,className:H(`peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input bg-card text-primary-foreground transition-colors outline-none focus-visible:outline-2 focus-visible:outline-[var(--app-focus-ring)] focus-visible:outline-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-checked:border-primary data-checked:bg-primary`,e),...t,children:(0,U.jsx)(Ko,{"data-slot":`checkbox-indicator`,className:`grid place-content-center text-current transition-none [&>svg]:size-3.5`,children:(0,U.jsx)(_h,{})})})}var yh={invalid_access:`Invalid access`,rate_limited:`Rate limited`,service_unavailable:`Service unavailable`,request_rejected:`Request rejected`,transport:`Network failure`};function bh(e){return e===null?null:`${e} ${e===1?`alert`:`alerts`} retrieved`}function xh(e,t){if(e===`cancelling`)return`Cancellation requested. The current request may continue until its timeout.`;if(e===`fetching`){let e=bh(t);return e?`Access confirmed. Fetching enabled alerts. ${e}.`:`Access confirmed. Fetching enabled alerts.`}return`Credentials locked. Checking access.`}function Sh({state:e,number:t,title:n,description:r}){return(0,U.jsxs)(`li`,{"data-state":e,children:[(0,U.jsx)(`span`,{"aria-hidden":`true`,children:t}),(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`strong`,{children:n}),(0,U.jsx)(`p`,{children:r})]})]})}function Ch({validator:e,onValidated:t,allowTokenSaving:n=!0,initialCluster:r,initialSavedToken:i,initialTokenError:a,savedTokenNeedsReplacement:o=!1,headingRef:s,fetchWorkflow:c}){let l=i?.cluster??r??null,u=(0,_.useRef)(null),d=(0,_.useRef)(null),f=(0,_.useRef)(!1),[p,m]=(0,_.useState)(l),[h,g]=(0,_.useState)(null),[v,y]=(0,_.useState)(null),[b,x]=(0,_.useState)(o?a??null:null),[S,C]=(0,_.useState)(i!==void 0||o),[w,T]=(0,_.useState)(!1),[E,D]=(0,_.useState)(!1),[O,k]=(0,_.useState)(!1),[ee,A]=(0,_.useState)(!1),j=c?.state.kind===`active`?c.state:null,M=c?.state.kind===`failed`?c.state:null,N=j!==null||M!==null,P=M?`failed`:j?.phase??`validating`,F=j?.retrievedCount??null,I=j?.accessConfirmed??M?.accessConfirmed??!1,te=M?.message??``,ne=M?.diagnostic,re=M?.failureStage??`retrieval`,ie=M?.retryAllowed??!1,L=j?.showProgress??M!==null;(0,_.useEffect)(()=>{if(a){if(o){C(!0),x(a),y(null);return}C(!1),x(null),y(a),k(!0)}},[a,o]),(0,_.useEffect)(()=>{N||i||o||!S||(C(!1),x(null),k(!0))},[N,i,o,S]),(0,_.useLayoutEffect)(()=>{!O||S||E||N||(d.current?.focus(),k(!1))},[O,N,E,S]),(0,_.useEffect)(()=>{if(!S||!i||N||f.current)return;let n=!0;return f.current=!0,D(!0),x(null),(async()=>{try{let r=await e.validate({source:`saved-token`,cluster:i.cluster});if(!n)return;if(D(!1),r.outcome===`valid`){t({credentialSource:`saved-token`,cluster:i.cluster,saveToken:!1});return}x(Th(r))}catch{if(!n)return;D(!1),x(`The saved token could not be validated. Enter a replacement token; it has not been deleted.`)}})(),()=>{n=!1}},[N,i,t,S,e]);let R=e=>{m(e),g(null)},ae=()=>{m(null),g(null)},oe=e=>{y(e),k(!0)},se=()=>{d.current&&(d.current.value=``)},ce=async(r,i)=>{D(!0),y(null);try{let a=await e.validate({source:`entered-token`,cluster:r,token:i});if(D(!1),a.outcome===`valid`){se(),t({credentialSource:`entered-token`,cluster:r,token:i,saveToken:n&&w});return}se(),oe(wh(a))}catch{D(!1),se(),oe(`The access token could not be validated. Try again.`)}},le=e=>{if(e.preventDefault(),N||S||E)return;if(!p){g(`Select a cluster from the list.`),u.current?.focus();return}let t=d.current?.value.trim()??``;if(!t){oe(`Enter an access token.`);return}ce(p,t)},ue=()=>{C(!1),x(null),y(null),k(!0)},de=()=>{c?.cancel()},fe=()=>{c?.reset()},pe=()=>{if(P===`cancelling`){c?.reset();return}de()},me=P===`validating`||P===`cancelling`&&!I?`active`:P===`failed`&&re===`access`?`failed`:I?`complete`:`pending`,he=P===`fetching`||P===`cancelling`&&I?`active`:P===`failed`&&re===`retrieval`?`failed`:P===`failed`&&re===`access`?`pending`:I?`complete`:`pending`,ge=L&&P!==`failed`;return(0,U.jsxs)(`section`,{className:`shell-panel credentials-panel`,"aria-labelledby":`credentials-heading`,children:[(0,U.jsx)(`h1`,{ref:s,id:`credentials-heading`,tabIndex:-1,children:`Credentials`}),(0,U.jsx)(`p`,{className:`credentials-introduction`,children:`Provide credentials to fetch enabled alerts.`}),(0,U.jsxs)(`form`,{className:`credentials-form`,noValidate:!0,onSubmit:le,children:[(0,U.jsxs)(jp,{className:`gap-5`,children:[(0,U.jsx)(ah,{selectedCluster:p,error:h,disabled:N||E||S,triggerRef:u,onSelected:R,onSearchChanged:ae}),(0,U.jsx)(Gp,{inputRef:d,error:v,savedTokenError:b,usingSavedToken:S,isValidating:E,locked:N,onUseDifferentToken:ue}),!S&&n?(0,U.jsxs)(Np,{orientation:`horizontal`,className:`save-token-field`,children:[(0,U.jsx)(vh,{id:`save-token`,checked:w,disabled:E||N,onCheckedChange:e=>T(e===!0)}),(0,U.jsxs)(Pp,{children:[(0,U.jsx)(Fp,{htmlFor:`save-token`,children:`Save token on this device`}),(0,U.jsx)(Ip,{children:`The token will be stored in the local token.json file on this device.`})]})]}):null,N?null:(0,U.jsx)(Tp,{type:`submit`,disabled:S||E,children:E?`Validating access`:`Fetch enabled alerts`})]}),N&&L?(0,U.jsxs)(`ol`,{className:`fetch-timeline`,"aria-label":`Extraction progress`,children:[(0,U.jsx)(Sh,{state:`complete`,number:1,title:`Credentials locked`,description:`The active connection remains visible above.`}),(0,U.jsx)(Sh,{state:me,number:2,title:`Access check`,description:me===`complete`?`Access confirmed.`:me===`failed`?`Access check needs attention.`:`Checking access.`}),(0,U.jsx)(Sh,{state:he,number:3,title:`Enabled-alert retrieval`,description:P===`cancelling`?`Cancellation requested. The current request may continue until its timeout.`:he===`failed`?`Retrieval needs attention.`:bh(F)??`Fetching enabled alerts.`})]}):null,ge?(0,U.jsxs)(U.Fragment,{children:[(0,U.jsxs)(`div`,{className:`fetch-status`,"aria-hidden":`true`,children:[(0,U.jsx)(`span`,{className:`fetch-status-indicator`}),(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`strong`,{children:P===`cancelling`?`Cancelling extraction`:P===`fetching`?`Fetching enabled alerts`:`Checking access`}),(0,U.jsx)(`p`,{children:xh(P,F)})]})]}),(0,U.jsx)(`p`,{className:`sr-only`,role:`status`,"aria-live":`polite`,"aria-atomic":`true`,children:xh(P,F)})]}):null,N&&P===`failed`?(0,U.jsxs)(Dp,{variant:`destructive`,className:`fetch-failure`,children:[(0,U.jsx)(Op,{children:ne?`${yh[ne.category]}${ne.status===void 0?``:` (HTTP ${ne.status})`}`:`Enabled alerts could not be retrieved`}),(0,U.jsxs)(kp,{children:[(0,U.jsx)(`p`,{children:ne?.guidance??te}),(0,U.jsx)(`p`,{children:`No partial alerts were saved.`})]}),(0,U.jsxs)(`div`,{className:`fetching-actions`,children:[ie?(0,U.jsx)(Tp,{type:`button`,onClick:()=>c?.retry(),children:`Retry fetch`}):null,(0,U.jsx)(Tp,{type:`button`,variant:`outline`,onClick:fe,children:`Change credentials`})]})]}):null,N&&P!==`failed`?(0,U.jsxs)(`div`,{className:`fetching-actions`,children:[(0,U.jsx)(Tp,{type:`button`,variant:`ghost`,disabled:P===`cancelling`,onClick:de,children:P===`cancelling`?`Cancellation requested`:`Cancel`}),(0,U.jsxs)(oh,{open:ee,onOpenChange:A,children:[(0,U.jsx)(sh,{asChild:!0,children:(0,U.jsx)(Tp,{type:`button`,variant:`ghost`,children:`Change connection`})}),(0,U.jsxs)(uh,{children:[(0,U.jsxs)(dh,{children:[(0,U.jsx)(ph,{children:`Change connection?`}),(0,U.jsx)(mh,{children:`This will cancel the active fetch. Partial alerts will not be saved.`})]}),(0,U.jsxs)(fh,{children:[(0,U.jsx)(gh,{children:`Keep fetching`}),(0,U.jsx)(hh,{onClick:pe,children:`Change connection`})]})]})]})]}):null]})]})}function wh(e){return e.outcome===`invalid-token`?`The access token is invalid or expired.`:`The access token could not be validated. Try again.`}function Th(e){return e.outcome===`invalid-saved-token`||e.outcome===`invalid-token`?`The saved token is invalid or expired. Enter a replacement token; it has not been deleted.`:`The saved token could not be validated. Enter a replacement token; it has not been deleted.`}var Eh=`Cancellation could not be requested. Check the local connection and try again.`;function Dh(e){switch(e.state){case`validating_access`:return`validating`;case`fetching_enabled_alerts`:return`fetching`;case`cancelling`:return`cancelling`;default:return null}}function Oh(e,t){return e<=0||t.aborted?Promise.resolve():new Promise(n=>{let r=window.setTimeout(n,e);t.addEventListener(`abort`,()=>{window.clearTimeout(r),n()},{once:!0})})}function kh(e,t){return{kind:`active`,request:e,phase:`validating`,retrievedCount:null,accessConfirmed:!1,showProgress:t}}function Ah(e,t={}){let[n,r]=(0,_.useState)(null),i=(0,_.useRef)(null),a=(0,_.useRef)(0),o=(0,_.useRef)(null),s=(0,_.useRef)(null),c=(0,_.useRef)(null),l=(0,_.useRef)(!1),u=(0,_.useRef)(null),d=(0,_.useRef)(t);d.current=t,i.current=n;let f=(0,_.useCallback)((e,t)=>{r(n=>{let r=n?.id===e?t(n):n;return i.current=r,r})},[]),p=(0,_.useCallback)(e=>{f(e,e=>e.state.kind===`active`?{...e,state:{kind:`failed`,request:e.state.request,message:Eh,retryAllowed:!1,failureStage:`retrieval`,accessConfirmed:e.state.accessConfirmed}}:e)},[f]),m=(0,_.useCallback)((t,n)=>{let r=u.current;if(r?.operationId===t)return r.promise;if(!e)return p(t),Promise.resolve(!1);let i=e.cancelExtraction(n).then(e=>(e||p(t),e)).catch(()=>(p(t),!1));return u.current={operationId:t,promise:i},i},[e,p]),h=(0,_.useCallback)(e=>{a.current+=1,s.current=null,c.current=null,l.current=!1,u.current=null;let t={id:a.current,state:kh(e,!1)};o.current={id:t.id,request:e},i.current=t,r(t)},[]),g=(0,_.useCallback)(()=>{let e=i.current;if(e?.state.kind!==`failed`||!e.state.retryAllowed)return;let t=c.current??void 0;a.current+=1,s.current=null,l.current=!1,u.current=null;let n={id:a.current,retryAttemptId:t,state:kh(e.state.request,!0)};o.current={id:n.id,request:e.state.request,retryAttemptId:t},i.current=n,r(n)},[]),v=(0,_.useCallback)(()=>{let e=i.current;e?.state.kind===`active`&&(l.current=!0,f(e.id,e=>e.state.kind===`active`?{...e,state:{...e.state,phase:`cancelling`,showProgress:!0}}:e),s.current!==null&&m(e.id,s.current))},[m,f]),y=(0,_.useCallback)(()=>{a.current+=1,s.current=null,c.current=null,l.current=!1,u.current=null,o.current=null,i.current=null,r(null)},[]),b=n?.id;return(0,_.useEffect)(()=>{let t=o.current;if(!t||t.id!==b)return;let n=new AbortController,a=!0,p=!1,h=()=>a&&!n.signal.aborted,g=e=>{h()&&(s.current=null,c.current=null,u.current=null,o.current?.id===t.id&&(o.current=null),r(e=>{let n=e?.id===t.id?null:e;return i.current=n,n}),e())},_=(e,n,r=!0,i,a)=>{!h()||l.current||(c.current=a??null,f(t.id,t=>t.state.kind===`active`?{...t,retryAttemptId:a,state:{kind:`failed`,request:t.state.request,message:e,...i===void 0?{}:{diagnostic:i},retryAllowed:r,failureStage:n,accessConfirmed:p}}:t))},v=async()=>{if(!l.current)return!1;let e=u.current;return e!==null&&!await e.promise||g(()=>d.current.onCancelled?.(t.request)),!0},y=e=>{let n=Dh(e);n!==null&&(e.state===`fetching_enabled_alerts`&&(p=!0),f(t.id,t=>t.state.kind===`active`?{...t,state:{...t.state,phase:n,...e.state===`fetching_enabled_alerts`?{retrievedCount:e.retrieved,accessConfirmed:!0}:{}}}:t))},x=async e=>{if(s.current=e.id,l.current){if(!await m(t.id,e.id))return!0;if(e.state===`complete`||e.state===`failed`||e.state===`cancelled`)return g(()=>d.current.onCancelled?.(t.request)),!0}return y(e),e.state===`complete`&&e.run?(g(()=>d.current.onComplete?.(e.run)),!0):e.state===`failed`&&e.failure?e.failure.category===`invalid_access`?(g(()=>d.current.onInvalidAccess?.(t.request,`Invalid access (HTTP ${e.failure?.status}). ${e.failure?.guidance}`)),!0):(_(Qm,p?`retrieval`:`access`,e.failure.retryable,e.failure,e.failure.retryable?e.id:void 0),!0):e.state===`cancelled`&&(g(()=>d.current.onCancelled?.(t.request)),!0)},S=async()=>{try{let r=t.retryAttemptId?await e?.retryExtraction(t.retryAttemptId,n.signal):await e?.startExtraction(t.request,n.signal);if(!h())return;if(!r||r.outcome===`failure`){if(await v())return;_(r?.outcome===`failure`?r.message:Qm,`access`);return}let i=r.attempt;for(;;){if(await x(i)||(await Oh(e?.pollIntervalMs??250,n.signal),!h()))return;let t=await e?.getExtraction(i.id,n.signal);if(!h())return;if(!t||t.outcome===`failure`){if(await v())return;_(t?.outcome===`failure`?t.message:Qm,p?`retrieval`:`access`);return}if(t.attempt.id!==i.id){if(await v())return;_(Qm,`retrieval`);return}i=t.attempt}}catch{if(!h()||await v())return;_(Qm,p?`retrieval`:`access`)}},C=t.retryAttemptId?null:window.setTimeout(()=>{f(t.id,e=>e.state.kind===`active`?{...e,state:{...e.state,showProgress:!0}}:e)},250);return S(),()=>{a=!1,n.abort(),C!==null&&window.clearTimeout(C)}},[e,b,m,f]),{state:n?.state??{kind:`idle`},start:h,retry:g,cancel:v,reset:y}}var jh=new Set([`global`,`site`,`device-group`,`device`]),Mh=new Set([`validating_access`,`fetching_enabled_alerts`,`cancelling`,`complete`,`failed`,`cancelled`]);function Nh(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Ph(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)}function Fh(e){return e===null||typeof e==`string`}function Ih(e,t){let n=Object.keys(e);return n.length===t.length&&n.every(e=>t.includes(e))}function Lh(e){return!Nh(e)||!Ih(e,[`kind`,`targets`])||!Ph(e.targets)||![`webhook`,`email`,`streaming`].includes(String(e.kind))?!1:e.kind!==`streaming`||e.targets.length===0}function Rh(e){return Nh(e)&&Ih(e,[`severity`,`operator`,`value`])&&typeof e.severity==`string`&&Fh(e.operator)&&Fh(e.value)}function zh(e){return Nh(e)&&Ih(e,[`number`,`duration`,`deliveryOptions`,`conditions`])&&typeof e.number==`number`&&Number.isSafeInteger(e.number)&&e.number>=0&&Fh(e.duration)&&Array.isArray(e.deliveryOptions)&&e.deliveryOptions.every(Lh)&&Array.isArray(e.conditions)&&e.conditions.every(Rh)}function Bh(e){return Nh(e)&&Ih(e,[`reason`,`referenceCount`,`assignmentCount`])&&(e.reason===`lookup-failed`||e.reason===`unresolved-references`)&&Vh(e.referenceCount)&&Vh(e.assignmentCount)}function Vh(e){return typeof e==`number`&&Number.isSafeInteger(e)&&e>0}function Hh(e){return!Nh(e)||!jh.has(String(e.scope))?!1:typeof e.id==`string`&&typeof e.name==`string`&&Fh(e.apiDisplayName)&&Fh(e.sourceType)&&Fh(e.category)&&Ph(e.severities)&&Array.isArray(e.notificationOptions)&&e.notificationOptions.every(Lh)&&Array.isArray(e.rules)&&e.rules.every(zh)&&Fh(e.target)&&Ph(e.conditions)&&Fh(e.duration)&&Fh(e.siteName)&&Fh(e.deviceGroupName)&&Fh(e.deviceId)&&Fh(e.serialNumber)&&Nh(e.identifiers)&&Object.values(e.identifiers).every(e=>typeof e==`string`)&&typeof e.isMapped==`boolean`}function Uh(e){if(!Nh(e))return!1;let t=e.cluster;return Nh(t)?Xm.find(e=>e.name===t.name&&e.origin===t.origin)!==void 0&&typeof e.id==`string`&&typeof e.fetchedAt==`string`&&e.completionState===`complete`&&typeof e.enabledAlertCount==`number`&&Number.isSafeInteger(e.enabledAlertCount)&&e.enabledAlertCount>=0&&Array.isArray(e.alerts)&&e.alerts.length===e.enabledAlertCount&&e.alerts.every(Hh)&&(e.notificationOptionError===null||Bh(e.notificationOptionError)):!1}function Wh(e){return!Nh(e)||!Array.isArray(e.runs)||e.latestRunId!==null&&typeof e.latestRunId!=`string`?!1:e.runs.every(Uh)&&(e.latestRunId===null?e.runs.length===0:e.runs.some(t=>t.id===e.latestRunId))}function Gh(e){return Number.isSafeInteger(e)&&Number(e)>=0}function Kh(e){return typeof e==`string`&&Object.prototype.hasOwnProperty.call(eh,e)}function qh(e,t){switch(e){case`invalid_access`:return t===401||t===403;case`rate_limited`:return t===429;case`service_unavailable`:return Number.isInteger(t)&&Number(t)>=500&&Number(t)<=599;case`request_rejected`:return Number.isInteger(t)&&Number(t)>=100&&Number(t)<=599&&t!==401&&t!==403&&t!==429&&!(Number(t)>=500&&Number(t)<=599);case`transport`:return t===void 0}}function Jh(e){return!Nh(e)||!Kh(e.category)?!1:typeof e.retryable==`boolean`&&e.guidance===eh[e.category]&&qh(e.category,e.status)}function Yh(e){return!Nh(e)||typeof e.id!=`string`||!Mh.has(String(e.state))||!Gh(e.retrieved)||!(e.total===null||Gh(e.total))?!1:e.state===`complete`?Uh(e.run):e.state===`failed`?Jh(e.failure):e.run===void 0&&e.failure===void 0}async function Xh(e){try{let t=await e.json();return Yh(t)?t:null}catch{return null}}async function Zh(e){try{let t=await e.json();return Wh(t)?t:null}catch{return null}}var Qh=class{pollIntervalMs;constructor({pollIntervalMs:e=250}={}){this.pollIntervalMs=e}async listCompletedRuns(e){try{let t=await fetch(`/api/extractions/runs`,{signal:e});return t.ok?Zh(t):null}catch{return null}}async startExtraction(e,t){return this.requestExtraction(`/api/extractions`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e.credentialSource===`entered-token`?{credentialSource:`entered-token`,cluster:e.cluster.name,token:e.token,saveToken:e.saveToken}:{credentialSource:`saved-token`,cluster:e.cluster.name}),signal:t})}async getExtraction(e,t){return this.requestExtraction(`/api/extractions/${encodeURIComponent(e)}`,{signal:t},e)}async retryExtraction(e,t){return this.requestExtraction(`/api/extractions/${encodeURIComponent(e)}/retry`,{method:`POST`,signal:t})}async cancelExtraction(e){try{return(await fetch(`/api/extractions/${encodeURIComponent(e)}`,{method:`DELETE`})).ok}catch{return!1}}async requestExtraction(e,t,n){try{let r=await fetch(e,t);if(!r.ok)return{outcome:`failure`,message:r.status===409?$m:Zm};let i=await Xh(r);return i===null||n!==void 0&&i.id!==n?{outcome:`failure`,message:Qm}:{outcome:`attempt`,attempt:i}}catch{return{outcome:`failure`,message:Qm}}}},$h=`Not returned in source data`,eg=[{scope:`global`,label:`Global`,singular:`Global`},{scope:`site`,label:`Sites`,singular:`Site`},{scope:`device-group`,label:`Device Groups`,singular:`Device Group`},{scope:`device`,label:`Devices`,singular:`Device`}];function tg(e){return eg.find(t=>t.scope===e).singular}var ng=new Map(eg.map(({scope:e},t)=>[e,t])),rg={site:[`siteid`,`siteuuid`],"device-group":[`groupid`,`devicegroupid`,`devicegroupuuid`],device:[`deviceid`,`serialnumber`,`serial`]};function ig(e){return e.trim().length>0}function ag(e){return e.trim().toLocaleLowerCase()===`not provided`}function og(e){return e.filter(e=>ig(e)&&!ag(e))}function sg(e){return og(e.severities)}function cg(e){let t=new Map;for(let n of e)for(let e of new Set(sg(n)))t.set(e,(t.get(e)??0)+1);return[...t.entries()].map(([e,t])=>({value:e,assignmentCount:t})).sort((e,t)=>ug(e.value)-ug(t.value)||e.value.localeCompare(t.value,void 0,{sensitivity:`base`}))}var lg=[`critical`,`major`,`minor`,`warning`];function ug(e){let t=lg.indexOf(e.toLocaleLowerCase());return t===-1?lg.length:t}function dg(e){switch(e){case`webhook`:return`Webhook`;case`email`:return`Email`;case`streaming`:return`Streaming`}}function fg(e){return[`email`,`webhook`,`streaming`].map(t=>({kind:t,count:e.filter(e=>e.notificationOptions.some(e=>e.kind===t)).length})).filter(({count:e})=>e>0)}function pg(e,t){return t.size===0||e!==null&&t.has(e)}function mg(e,t){return t.size===0||e.some(e=>t.has(e))}function hg(e){return e.name||e.apiDisplayName||`Unnamed alert`}function gg(e){return[e.id,e.scope,e.name,e.apiDisplayName,e.sourceType,e.category,...e.severities,e.target,...e.conditions,e.duration,...e.rules.flatMap(e=>[String(e.number),e.duration,...e.conditions.flatMap(e=>[e.severity,e.operator,e.value]),...e.deliveryOptions.flatMap(e=>[dg(e.kind),...e.targets])]),...e.notificationOptions.flatMap(e=>[dg(e.kind),...e.targets]),e.siteName,e.deviceGroupName,e.deviceId,e.serialNumber,...Object.entries(e.identifiers).flat()].filter(e=>typeof e==`string`).join(` +`).toLocaleLowerCase()}function _g(e,t){let n=t.search.trim().toLocaleLowerCase();return e.filter(e=>gg(e).includes(n)&&pg(e.category,t.categories)&&mg(sg(e),t.severities)&&pg(e.scope,t.scopes)&&mg(e.notificationOptions.map(e=>e.kind),t.notificationKinds))}function vg(e){switch(e.scope){case`global`:return`Global`;case`site`:return e.siteName??e.target??`Unnamed site`;case`device-group`:return e.deviceGroupName??e.target??`Unnamed device group`;case`device`:return e.target??e.serialNumber??e.deviceId??`Unnamed device`}}function yg(e){return e.scope===`device`&&(e.serialNumber||e.deviceId)||vg(e)}function bg(e){return e.replaceAll(/[^a-z0-9]/gi,``).toLocaleLowerCase()}function xg(e){if(e.scope===`global`)return null;let t=rg[e.scope];for(let n of t){let t=Object.entries(e.identifiers).find(([e,t])=>bg(e)===n&&t.length>0);if(t)return[n,t[1]]}if(e.scope===`device`){if(e.deviceId)return[`deviceid`,e.deviceId];if(e.serialNumber)return[`serialnumber`,e.serialNumber]}return null}function Sg(e){if(e.scope===`global`)return`global`;let t=xg(e);return t?`${e.scope}:${t[0]}:${t[1]}`:`${e.scope}:name:${vg(e).toLocaleLowerCase()}`}function Cg(e,t){return e.localeCompare(t,void 0,{sensitivity:`base`})}function wg(e,t){return Cg(hg(e),hg(t))||Cg(e.category??``,t.category??``)||Cg(e.id,t.id)}function Tg(e){let t=new Map;for(let n of e){let e=Sg(n),r=t.get(e)??[];r.push(n),t.set(e,r)}return t}function Eg(e,t){return eg.map(({scope:n,label:r})=>{let i=e.filter(e=>e.scope===n),a=t.filter(e=>e.scope===n),o=Tg(i),s=[...Tg(a).entries()].map(([e,t])=>{let r=o.get(e)??t;return{key:e,scope:n,name:vg(r[0]),sectionName:yg(r[0]),configuredAlertCount:r.length,matchingAlertCount:t.length,assignments:[...r].sort(wg),matchingAssignments:[...t].sort(wg)}}).sort((e,t)=>Cg(e.sectionName,t.sectionName)||Cg(e.key,t.key));return{scope:n,label:r,configuredAlertCount:i.length,matchingAlertCount:a.length,scopes:s}})}function Dg(e){return e.category===null?`category:null`:`category:${e.category}`}function Og(e){let t=new Map;for(let n of e){let e=Dg(n),r=t.get(e)??[];r.push(n),t.set(e,r)}return t}function kg(e,t){return Cg(hg(e),hg(t))||(ng.get(e.scope)??0)-(ng.get(t.scope)??0)||Cg(vg(e),vg(t))||Cg(e.id,t.id)}function Ag(e,t){let n=Og(e);return[...Og(t).entries()].map(([e,t])=>{let r=[...n.get(e)??t].sort(kg),i=[...t].sort(kg);return{key:e,category:r[0].category,configuredAssignmentCount:r.length,matchingAssignmentCount:i.length,assignments:r,matchingAssignments:i}}).sort((e,t)=>e.category===null&&t.category!==null?1:e.category!==null&&t.category===null?-1:Cg(e.category??``,t.category??``)||Cg(e.key,t.key))}function jg(e){let t=e.toLowerCase();return[`critical`,`major`,`minor`,`warning`].includes(t)?`severity-${t}`:void 0}var Mg=Ot(`group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 [&>svg]:pointer-events-none [&>svg]:size-3!`,{variants:{variant:{default:`bg-primary text-primary-foreground [a]:hover:bg-primary/80`,secondary:`bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80`,destructive:`bg-destructive/10 text-destructive focus-visible:ring-destructive/20 [a]:hover:bg-destructive/20`,outline:`border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground`,ghost:`hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50`,link:`text-primary underline-offset-4 hover:underline`}},defaultVariants:{variant:`default`}});function Ng({className:e,variant:t=`default`,asChild:n=!1,...r}){let i=n?Rt:`span`;return(0,U.jsx)(i,{"data-slot":`badge`,"data-variant":t,className:H(Mg({variant:t}),e),...r})}function Pg({className:e,size:t=`default`,...n}){return(0,U.jsx)(`div`,{"data-slot":`card`,"data-size":t,className:H(`group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl`,e),...n})}function Fg({className:e,...t}){return(0,U.jsx)(`div`,{"data-slot":`card-header`,className:H(`group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)`,e),...t})}function Ig({className:e,...t}){return(0,U.jsx)(`div`,{"data-slot":`card-title`,className:H(`text-base leading-snug font-medium group-data-[size=sm]/card:text-sm`,e),...t})}function Lg({className:e,...t}){return(0,U.jsx)(`div`,{"data-slot":`card-description`,className:H(`text-sm text-muted-foreground`,e),...t})}function Rg({className:e,...t}){return(0,U.jsx)(`div`,{"data-slot":`card-action`,className:H(`col-start-2 row-span-2 row-start-1 self-start justify-self-end`,e),...t})}function zg({className:e,...t}){return(0,U.jsx)(`div`,{"data-slot":`card-content`,className:H(`px-(--card-spacing)`,e),...t})}function Bg({className:e,...t}){return(0,U.jsx)(`div`,{"data-slot":`card-footer`,className:H(`flex items-center rounded-b-xl border-t bg-muted/50 p-(--card-spacing)`,e),...t})}function Vg({className:e,...t}){return(0,U.jsx)(`div`,{"data-slot":`table-container`,className:`relative w-full overflow-x-auto`,children:(0,U.jsx)(`table`,{"data-slot":`table`,className:H(`w-full caption-bottom text-sm`,e),...t})})}function Hg({className:e,...t}){return(0,U.jsx)(`thead`,{"data-slot":`table-header`,className:H(`[&_tr]:border-b`,e),...t})}function Ug({className:e,...t}){return(0,U.jsx)(`tbody`,{"data-slot":`table-body`,className:H(`[&_tr:last-child]:border-0`,e),...t})}function Wg({className:e,...t}){return(0,U.jsx)(`tr`,{"data-slot":`table-row`,className:H(`border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted`,e),...t})}function Gg({className:e,...t}){return(0,U.jsx)(`th`,{"data-slot":`table-head`,className:H(`h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0`,e),...t})}function Kg({className:e,...t}){return(0,U.jsx)(`td`,{"data-slot":`table-cell`,className:H(`p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0`,e),...t})}function qg({delayDuration:e=0,...t}){return(0,U.jsx)(vp,{"data-slot":`tooltip-provider`,delayDuration:e,...t})}function Jg({...e}){return(0,U.jsx)(yp,{"data-slot":`tooltip`,...e})}function Yg({...e}){return(0,U.jsx)(bp,{"data-slot":`tooltip-trigger`,...e})}function Xg({className:e,sideOffset:t=0,children:n,...r}){return(0,U.jsx)(xp,{children:(0,U.jsxs)(Sp,{"data-slot":`tooltip-content`,sideOffset:t,className:H(`z-50 inline-flex w-fit max-w-xs origin-(--radix-tooltip-content-transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pr-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95`,e),...r,children:[n,(0,U.jsx)(Cp,{className:`z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground`})]})})}var Zg={webhook:I,email:j,streaming:N};function Qg({options:e,targetLimit:t,expanded:n=!1,controls:r,onExpand:i}){if(e.length===0)return(0,U.jsx)(`span`,{children:$h});let a=new Map;for(let t of e){let e=a.get(t.kind)??[];for(let n of t.targets)e.includes(n)||e.push(n);a.set(t.kind,e)}return(0,U.jsx)(`div`,{className:`notification-options`,children:(0,U.jsx)(`div`,{className:`notification-options-list`,children:[...a].map(([e,a])=>{let o=Zg[e],s=t===void 0?a:a.slice(0,t),c=a.length-s.length;return(0,U.jsxs)(`div`,{className:`notification-option`,children:[(0,U.jsxs)(`div`,{className:`notification-option-label`,children:[(0,U.jsx)(o,{"aria-hidden":`true`}),(0,U.jsx)(`span`,{children:dg(e)})]}),s.length>0?(0,U.jsx)(`span`,{className:`notification-option-target`,children:s.join(`, `)}):null,c>0&&r!==void 0&&i!==void 0?(0,U.jsxs)(Tp,{type:`button`,variant:`outline`,className:`notification-options-more`,"aria-expanded":n,"aria-controls":r,onClick:i,children:[`+`,c,` more`]}):null]},e)})})})}var $g=2,e_=[`alert`,`context`,`rule`,`notification`,`details`];function t_(e,t,n=`${t}s`){return`${e} ${e===1?t:n}`}function n_(e){return Array.from({length:e.length},(t,n)=>e.charCodeAt(n).toString(16).padStart(4,`0`)).join(``)}function r_(e){let t=og(e);return t.length>0?t.join(`; `):$h}function i_(e){return e===null?$h:r_([e])}function a_({severity:e,assignmentCount:t}){return(0,U.jsxs)(Ng,{variant:`outline`,className:H(`alert-review-severity-badge`,jg(e)),children:[e,t===void 0?null:` ${t}`]})}function o_({alert:e}){let t=sg(e);return t.length===0?(0,U.jsx)(`span`,{children:$h}):(0,U.jsx)(`div`,{className:`alert-review-badges`,children:t.map((e,t)=>(0,U.jsx)(a_,{severity:e},`${e}-${t}`))})}function s_(e){return/^\d+(?:\.\d+)?$/.test(e)?`${e} min`:e}function c_(e){let t=[e.operator,e.value].filter(e=>e!==null);return t.length>0?t.join(` `):null}function l_({alert:e}){if(e.rules.length===0)return(0,U.jsx)(o_,{alert:e});let[t]=e.rules;if(e.rules.length===1&&t.conditions.length===1){let[e]=t.conditions,n=c_(e);return(0,U.jsxs)(`div`,{className:`alert-review-rule-inline`,children:[(0,U.jsx)(a_,{severity:e.severity}),n===null?null:(0,U.jsx)(`span`,{className:`alert-review-rule-threshold`,children:n}),t.duration===null?null:(0,U.jsxs)(`span`,{className:`alert-review-rule-duration`,children:[`for `,s_(t.duration)]})]})}let n=e.rules.reduce((e,t)=>e+t.conditions.length,0),r=new Map;for(let t of e.rules.flatMap(e=>e.conditions.map(e=>e.severity)))r.set(t.toLowerCase(),t);for(let t of sg(e))r.has(t.toLowerCase())||r.set(t.toLowerCase(),t);let i=[...r.values()];return(0,U.jsxs)(`div`,{className:`alert-review-rule-overview`,children:[i.length>0?(0,U.jsx)(`div`,{className:`alert-review-badges`,children:i.map(e=>(0,U.jsx)(a_,{severity:e},e))}):null,(0,U.jsxs)(`div`,{className:`alert-review-rule-summary`,children:[(0,U.jsxs)(`span`,{children:[t_(e.rules.length,`rule`),`,`,` `,t_(n,`condition`)]}),(0,U.jsx)(`span`,{className:`alert-review-rule-expand-cue`,children:`— Expand details`})]})]})}function u_({rules:e,detailId:t}){return(0,U.jsx)(`div`,{className:`alert-review-rule-inspector`,children:e.map(e=>{let n=`${t}-source-rule-${e.number}`;return(0,U.jsxs)(`section`,{className:`alert-review-source-rule`,"aria-labelledby":n,children:[(0,U.jsxs)(`aside`,{className:`alert-review-source-rule-meta`,children:[(0,U.jsxs)(`h5`,{id:n,children:[`Rule `,e.number+1]}),(0,U.jsx)(`span`,{className:`alert-review-source-rule-duration`,children:e.duration===null?`Duration: not set`:`Duration: ${s_(e.duration)}`}),(0,U.jsx)(`span`,{className:`alert-review-source-rule-delivery-label`,children:`Delivery options`}),(0,U.jsx)(Qg,{options:e.deliveryOptions})]}),(0,U.jsx)(`div`,{className:`alert-review-source-rule-conditions`,children:e.conditions.length===0?(0,U.jsx)(`span`,{className:`alert-review-no-details`,children:`No conditions returned`}):e.conditions.map((e,t)=>{let n=c_(e);return(0,U.jsxs)(`div`,{className:`alert-review-source-rule-condition`,children:[(0,U.jsx)(a_,{severity:e.severity}),(0,U.jsx)(`span`,{className:H(`alert-review-rule-threshold`,n===null&&`alert-review-rule-severity-only`),children:n??`Severity only`})]},`${e.severity}-${t}`)})})]},e.number)})})}function d_({expanded:e,controls:t,label:n,onClick:r}){let i=`${e?`Collapse`:`Expand`} ${n}`;return(0,U.jsxs)(Jg,{children:[(0,U.jsx)(Yg,{asChild:!0,children:(0,U.jsx)(Tp,{type:`button`,variant:`outline`,size:`icon`,className:`alert-review-expand-button`,"aria-label":i,"aria-expanded":e,"aria-controls":t,onClick:r,children:(0,U.jsx)(e?ee:A,{"aria-hidden":`true`})})}),(0,U.jsx)(Xg,{side:`right`,children:i})]})}function f_({label:e,children:t}){return(0,U.jsxs)(`div`,{className:`alert-review-detail-field`,children:[(0,U.jsx)(`dt`,{children:e}),(0,U.jsx)(`dd`,{className:`alert-review-wrap`,children:t})]})}function p_({values:e}){let t=og(e);return t.length===0?(0,U.jsx)(`span`,{children:$h}):(0,U.jsx)(`ul`,{className:`alert-review-detail-values`,children:t.map((e,t)=>(0,U.jsx)(`li`,{children:e},`${e}-${t}`))})}function m_(e){return e===null?[]:og([e])}function h_(e){let t=new Map;for(let n of e.notificationOptions){let e=t.get(n.kind)??new Set;n.targets.forEach(t=>e.add(t)),t.set(n.kind,e)}return[...t.values()].some(e=>e.size>$g)}function g_(e){return e.rules.length>0||og(e.conditions).length>0||m_(e.duration).length>0||h_(e)}function __({alert:e,detailId:t}){let n=`${t}-heading`,r=og(e.conditions),i=m_(e.duration),a=e.rules.length>0,o=e.rules.some(e=>e.conditions.length>0),s=e.rules.some(e=>e.duration!==null),c=h_(e);return(0,U.jsxs)(`section`,{id:t,className:`alert-review-detail-region`,"data-testid":`details-${e.id}`,"aria-labelledby":n,children:[(0,U.jsx)(`div`,{className:`alert-review-detail-heading`,children:(0,U.jsx)(`h4`,{id:n,children:`Additional configuration`})}),(0,U.jsxs)(`dl`,{className:`alert-review-details`,children:[!o&&r.length>0?(0,U.jsx)(f_,{label:a?`Alert-level conditions`:`Conditions`,children:(0,U.jsx)(p_,{values:r})}):null,!s&&i.length>0?(0,U.jsx)(f_,{label:a?`Alert-level duration`:`Duration`,children:i.join(`; `)}):null,!a&&c?(0,U.jsx)(f_,{label:`Notification options`,children:(0,U.jsx)(Qg,{options:e.notificationOptions})}):null]}),a?(0,U.jsx)(u_,{rules:e.rules,detailId:t}):null]})}function v_({alert:e,detailId:t}){return(0,U.jsx)(Wg,{className:`alert-review-detail-row`,children:(0,U.jsx)(Kg,{colSpan:e_.length,className:`alert-review-detail-cell`,children:(0,U.jsx)(__,{alert:e,detailId:t})})})}function y_({ariaLabel:e,className:t,assignments:n,expandedAssignmentIds:r,contextHeader:i,contextCell:a,detailContext:o,detailIdPrefix:s,onAssignmentExpandedChange:c}){return(0,U.jsxs)(Vg,{"aria-label":e,className:H(`alert-review-table`,t),children:[(0,U.jsx)(`colgroup`,{children:e_.map(e=>(0,U.jsx)(`col`,{className:`alert-review-column-${e}`},e))}),(0,U.jsx)(Hg,{children:(0,U.jsxs)(Wg,{children:[(0,U.jsx)(Gg,{children:`Alert`}),(0,U.jsx)(Gg,{children:i}),(0,U.jsx)(Gg,{children:`Rule`}),(0,U.jsx)(Gg,{children:`Notification options`}),(0,U.jsx)(Gg,{children:`Details`})]})}),(0,U.jsx)(Ug,{children:n.map(e=>{let t=r.has(e.id),n=hg(e),i=o(e),l=`${s}-${n_(e.id)}`,u=g_(e);return(0,U.jsxs)(_.Fragment,{children:[(0,U.jsxs)(Wg,{children:[(0,U.jsx)(Kg,{className:`alert-review-wrap`,children:(0,U.jsxs)(`div`,{className:`alert-review-value-with-badge`,children:[(0,U.jsx)(`span`,{className:`alert-review-primary-value`,children:n}),e.isMapped?null:(0,U.jsx)(Ng,{variant:`outline`,className:`alert-review-unmapped-badge`,children:`Unmapped alert`})]})}),(0,U.jsx)(Kg,{className:`alert-review-wrap`,children:a(e)}),(0,U.jsx)(Kg,{className:`alert-review-wrap`,children:(0,U.jsx)(l_,{alert:e})}),(0,U.jsx)(Kg,{className:`alert-review-wrap`,children:(0,U.jsx)(Qg,{options:e.notificationOptions,targetLimit:$g,expanded:t,controls:l,onExpand:()=>c(e.id,!t)})}),(0,U.jsx)(Kg,{children:u?(0,U.jsx)(d_,{expanded:t,controls:l,label:`details for ${n} at ${i}`,onClick:()=>c(e.id,!t)}):(0,U.jsx)(`span`,{className:`alert-review-no-details`,children:`No additional details`})})]}),t&&u?(0,U.jsx)(v_,{alert:e,detailId:l}):null]},l)})})]})}function b_({scope:e,expandedAssignmentIds:t,onAssignmentExpandedChange:n}){let r=`scope-section-${n_(e.key)}-heading`;return(0,U.jsxs)(`section`,{className:`alert-review-scope-section`,"aria-labelledby":r,children:[(0,U.jsx)(`div`,{className:`alert-review-scope-section-heading`,children:(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`h3`,{id:r,children:e.sectionName}),e.matchingAlertCount===e.configuredAlertCount?null:(0,U.jsxs)(`p`,{children:[e.matchingAlertCount,` of`,` `,t_(e.configuredAlertCount,`assignment`),` match`]})]})}),(0,U.jsx)(y_,{ariaLabel:`${e.sectionName} configured alerts`,className:`alert-review-assignment-table`,assignments:e.matchingAssignments,expandedAssignmentIds:t,contextHeader:`Category`,contextCell:e=>i_(e.category),detailContext:()=>e.sectionName,detailIdPrefix:`scope-assignment-details`,onAssignmentExpandedChange:n})]})}function x_({collections:e,expandedAssignmentIds:t,onAssignmentExpandedChange:n}){return(0,U.jsx)(`div`,{className:`alert-review-collections`,children:e.map(e=>e.configuredAlertCount===0?null:e.matchingAlertCount===0?(0,U.jsxs)(`p`,{className:`alert-review-empty`,children:[e.label,`: 0 of `,e.configuredAlertCount,` match`]},e.scope):(0,U.jsxs)(Pg,{className:`alert-review-card`,children:[(0,U.jsxs)(Fg,{className:`alert-review-card-header`,children:[(0,U.jsx)(Ig,{children:(0,U.jsx)(`h2`,{children:e.label})}),e.matchingAlertCount===e.configuredAlertCount?null:(0,U.jsxs)(Lg,{children:[e.matchingAlertCount,` of`,` `,e.configuredAlertCount,` configured alerts match`]}),(0,U.jsx)(Rg,{children:(0,U.jsx)(Ng,{variant:`secondary`,children:t_(e.scopes.length,`scope`)})})]}),(0,U.jsx)(zg,{className:`alert-review-card-content`,children:e.scope===`global`?(0,U.jsx)(y_,{ariaLabel:`Global configured alerts`,className:`alert-review-assignment-table`,assignments:e.scopes[0].matchingAssignments,expandedAssignmentIds:t,contextHeader:`Category`,contextCell:e=>i_(e.category),detailContext:()=>`Global`,detailIdPrefix:`scope-assignment-details`,onAssignmentExpandedChange:n}):(0,U.jsx)(`div`,{className:`alert-review-scope-sections`,children:e.scopes.map(e=>(0,U.jsx)(b_,{scope:e,expandedAssignmentIds:t,onAssignmentExpandedChange:n},e.key))})})]},e.scope))})}function S_({alert:e}){let t=vg(e);return(0,U.jsxs)(`div`,{className:`alert-review-configured-at`,children:[(0,U.jsx)(`span`,{className:`alert-review-primary-value`,children:t}),e.scope===`global`?null:(0,U.jsx)(`span`,{className:`alert-review-secondary-value`,children:tg(e.scope)})]})}function C_({categories:e,expandedAssignmentIds:t,onAssignmentExpandedChange:n}){return(0,U.jsx)(`div`,{className:`alert-review-collections`,children:e.map(e=>{let r=e.category??`Not returned in source data`;return(0,U.jsxs)(Pg,{className:`alert-review-card`,children:[(0,U.jsxs)(Fg,{className:`alert-review-card-header`,children:[(0,U.jsx)(Ig,{children:(0,U.jsx)(`h2`,{children:r})}),(0,U.jsx)(Rg,{children:(0,U.jsx)(Ng,{variant:`secondary`,children:t_(e.matchingAssignmentCount,`assignment`)})})]}),(0,U.jsx)(zg,{className:`alert-review-card-content`,children:(0,U.jsx)(y_,{ariaLabel:`${r} alert assignments`,className:`alert-review-alert-assignment-table`,assignments:e.matchingAssignments,expandedAssignmentIds:t,contextHeader:`Configured at`,contextCell:e=>(0,U.jsx)(S_,{alert:e}),detailContext:vg,detailIdPrefix:`alert-assignment-details`,onAssignmentExpandedChange:n})})]},e.key)})})}function w_(e){return(0,U.jsx)(`svg`,{"aria-hidden":`true`,fill:`none`,viewBox:`0 0 16 16`,...e,children:(0,U.jsx)(`path`,{d:`m3.5 8 3 3 6-6`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`1.5`})})}function T_({...e}){return(0,U.jsx)(Fd,{"data-slot":`dropdown-menu`,...e})}function E_({...e}){return(0,U.jsx)(Id,{"data-slot":`dropdown-menu-trigger`,...e})}function D_({className:e,align:t=`start`,sideOffset:n=4,...r}){return(0,U.jsx)(Ld,{children:(0,U.jsx)(Rd,{"data-slot":`dropdown-menu-content`,sideOffset:n,align:t,className:H(`z-50 max-h-(--radix-dropdown-menu-content-available-height) w-(--radix-dropdown-menu-trigger-width) min-w-32 overflow-x-hidden overflow-y-auto rounded-[8px] border border-border bg-popover p-1 text-popover-foreground`,e),...r})})}function O_({...e}){return(0,U.jsx)(zd,{"data-slot":`dropdown-menu-group`,...e})}function k_({className:e,children:t,checked:n,inset:r,...i}){return(0,U.jsxs)(Vd,{"data-slot":`dropdown-menu-checkbox-item`,"data-inset":r,className:H(`relative flex min-h-10 cursor-default items-center gap-1.5 rounded-[6px] pr-8 pl-2 text-[13px] font-medium leading-[18px] outline-none select-none focus:bg-accent focus:text-accent-foreground focus-visible:outline-2 focus-visible:outline-[var(--app-focus-ring)] focus-visible:outline-offset-[-2px] focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,e),checked:n,...i,children:[(0,U.jsx)(`span`,{className:`pointer-events-none absolute right-2 flex items-center justify-center`,"data-slot":`dropdown-menu-checkbox-item-indicator`,children:(0,U.jsx)(Hd,{children:(0,U.jsx)(w_,{})})}),t]})}function A_({className:e,inset:t,...n}){return(0,U.jsx)(Bd,{"data-slot":`dropdown-menu-label`,"data-inset":t,className:H(`px-2 py-1 text-[13px] font-medium leading-[18px] text-muted-foreground data-inset:pl-7`,e),...n})}function j_({className:e,orientation:t=`horizontal`,...n}){return(0,U.jsx)(Ff,{"data-slot":`tabs`,"data-orientation":t,className:H(`group/tabs flex gap-2 data-horizontal:flex-col`,e),...n})}var M_=Ot(`group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none`,{variants:{variant:{default:`bg-muted`,line:`gap-1 bg-transparent`}},defaultVariants:{variant:`default`}});function N_({className:e,variant:t=`default`,...n}){return(0,U.jsx)(If,{"data-slot":`tabs-list`,"data-variant":t,className:H(M_({variant:t}),e),...n})}function P_({className:e,...t}){return(0,U.jsx)(Lf,{"data-slot":`tabs-trigger`,className:H(`relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,`group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent`,`data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground`,`after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100`,e),...t})}function F_({className:e,...t}){return(0,U.jsx)(Rf,{"data-slot":`tabs-content`,className:H(`flex-1 text-sm outline-none`,e),...t})}function I_(e,t){let n=new Set(e);return n.has(t)?n.delete(t):n.add(t),n}function L_(e,t,n){let r=new Set(e);return n?r.add(t):r.delete(t),r}function R_(e,t){let n=!1,r=new Set;for(let i of e)t.has(i)?r.add(i):n=!0;return n?r:e}function z_({label:e,emptyLabel:t,triggerId:n,values:r,selected:i,formatValue:a=e=>e,onSelectedChange:o}){let s=i.size>0?`${i.size} selected`:t;return(0,U.jsxs)(T_,{children:[(0,U.jsx)(E_,{asChild:!0,children:(0,U.jsxs)(Tp,{id:n,type:`button`,variant:`outline`,className:`alert-review-filter-trigger`,"aria-label":`${e}: ${s}`,children:[(0,U.jsx)(`span`,{children:s}),(0,U.jsx)(ee,{"aria-hidden":`true`})]})}),(0,U.jsxs)(D_,{align:`start`,className:`alert-review-filter-menu`,children:[(0,U.jsx)(A_,{children:e}),(0,U.jsx)(O_,{children:r.map(e=>(0,U.jsx)(k_,{checked:i.has(e),onCheckedChange:()=>o(I_(i,e)),children:a(e)},e))})]})]})}function B_({alerts:e,matchingCount:t,hasFilters:n,collections:r,selectedSeverities:i,selectedScopes:a,selectedNotificationKinds:o,onToggleSeverity:s,onToggleScope:c,onToggleNotificationKind:l,onClearFilters:u}){let d=cg(e),f=r.filter(e=>e.configuredAlertCount>0),p=fg(e),m=e.filter(e=>!e.isMapped).length;return(0,U.jsx)(`div`,{className:`alert-summary-strip`,"aria-label":`Enabled alert summary`,children:(0,U.jsxs)(`div`,{className:`alert-summary-groups`,children:[(0,U.jsx)(`div`,{className:`alert-summary-group`,children:n?(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(`span`,{className:`alert-summary-total`,role:`status`,children:`${t} of ${e.length} match`}),(0,U.jsx)(Tp,{type:`button`,variant:`ghost`,onClick:u,children:`Clear`})]}):(0,U.jsxs)(`span`,{className:`alert-summary-total`,children:[e.length,` enabled alerts`]})}),d.length>0?(0,U.jsxs)(`div`,{className:`alert-summary-group alert-summary-severity`,children:[(0,U.jsx)(`span`,{className:`alert-summary-group-label`,children:`Severity`}),(0,U.jsx)(`div`,{className:`alert-summary-bar`,"aria-hidden":`true`,children:d.map(({value:e,assignmentCount:t})=>(0,U.jsx)(`span`,{className:H(`alert-summary-bar-segment`,jg(e),i.size>0&&!i.has(e)&&`is-dimmed`),style:{flexGrow:t}},e))}),(0,U.jsx)(`div`,{className:`alert-summary-chips`,children:d.map(({value:e,assignmentCount:t})=>(0,U.jsx)(`button`,{type:`button`,className:`alert-summary-toggle alert-summary-toggle-severity`,"aria-pressed":i.has(e),onClick:()=>s(e),children:(0,U.jsx)(a_,{severity:e,assignmentCount:t})},e))})]}):null,f.length>0?(0,U.jsxs)(`div`,{className:`alert-summary-group`,children:[(0,U.jsx)(`span`,{className:`alert-summary-group-label`,children:`Scope`}),f.map(e=>(0,U.jsxs)(`button`,{type:`button`,className:`alert-summary-toggle`,"aria-pressed":a.has(e.scope),onClick:()=>c(e.scope),children:[a.has(e.scope)?(0,U.jsx)(k,{"aria-hidden":`true`}):null,`${e.configuredAlertCount} ${e.label}`]},e.scope))]}):null,p.length>0?(0,U.jsxs)(`div`,{className:`alert-summary-group`,children:[(0,U.jsx)(`span`,{className:`alert-summary-group-label`,children:`Notification`}),p.map(({kind:e,count:t})=>{let n=V_[e],r=o.has(e);return(0,U.jsxs)(`button`,{type:`button`,className:`alert-summary-toggle`,"aria-pressed":r,onClick:()=>l(e),children:[r?(0,U.jsx)(k,{"aria-hidden":`true`}):(0,U.jsx)(n,{"aria-hidden":`true`}),`${t} ${dg(e)}`]},e)})]}):null,m>0?(0,U.jsx)(`div`,{className:`alert-summary-group`,children:(0,U.jsxs)(Ng,{variant:`outline`,className:`alert-review-unmapped-badge`,children:[m,` unmapped`]})}):null]})})}var V_={email:j,webhook:I,streaming:P};function H_(e){return[...new Set(e)].sort((e,t)=>e.localeCompare(t,void 0,{sensitivity:`base`}))}function U_({alerts:e,tab:t,onTabChange:n}){let[r,i]=(0,_.useState)(``),[a,o]=(0,_.useState)(new Set),[s,c]=(0,_.useState)(new Set),[l,u]=(0,_.useState)(new Set),[d,f]=(0,_.useState)(new Set),[p,m]=(0,_.useState)(new Set),[h,g]=(0,_.useState)(new Set),v=(0,_.useMemo)(()=>H_(e.flatMap(e=>e.category===null?[]:[e.category])),[e]),y=(0,_.useMemo)(()=>H_(e.flatMap(sg)),[e]),b=(0,_.useMemo)(()=>_g(e,{search:r,categories:a,severities:s,scopes:d,notificationKinds:l}),[e,r,a,s,d,l]),x=(0,_.useMemo)(()=>new Set(b.map(e=>e.id)),[b]);(0,_.useEffect)(()=>{m(e=>R_(e,x)),g(e=>R_(e,x))},[x]);let S=(0,_.useMemo)(()=>Eg(e,b),[e,b]),C=(0,_.useMemo)(()=>Ag(e,b),[e,b]),w=r.trim().length>0||a.size>0||s.size>0||d.size>0||l.size>0,T=(0,_.useMemo)(()=>fg(e).map(({kind:e})=>e),[e]),E=()=>{i(``),o(new Set),c(new Set),u(new Set),f(new Set)},D=S.filter(e=>e.configuredAlertCount>0).map(e=>e.scope);return(0,U.jsx)(qg,{children:(0,U.jsxs)(`div`,{className:`alert-review`,children:[(0,U.jsx)(B_,{alerts:e,matchingCount:b.length,hasFilters:w,collections:S,selectedSeverities:s,selectedScopes:d,selectedNotificationKinds:l,onToggleNotificationKind:e=>u(t=>I_(t,e)),onToggleSeverity:e=>c(t=>I_(t,e)),onToggleScope:e=>f(t=>I_(t,e)),onClearFilters:E}),(0,U.jsxs)(Pg,{className:`alert-review-filter-card`,children:[(0,U.jsx)(zg,{className:`alert-review-filter-content`,children:(0,U.jsxs)(jp,{className:`alert-review-filter-grid`,role:`group`,"aria-label":`Filters`,children:[(0,U.jsxs)(Np,{className:`alert-review-search-field`,children:[(0,U.jsx)(Fp,{className:`sr-only`,htmlFor:`alert-search`,children:`Search alerts`}),(0,U.jsx)(Rp,{id:`alert-search`,type:`search`,placeholder:`Search alerts`,value:r,onChange:e=>i(e.target.value)})]}),D.length>1?(0,U.jsxs)(Np,{children:[(0,U.jsx)(Fp,{className:`sr-only`,htmlFor:`scope-filter`,children:`Scope`}),(0,U.jsx)(z_,{label:`Scope`,emptyLabel:`All scope types`,triggerId:`scope-filter`,values:D,selected:d,formatValue:e=>eg.find(t=>t.scope===e).label,onSelectedChange:f})]}):null,v.length>1?(0,U.jsxs)(Np,{children:[(0,U.jsx)(Fp,{className:`sr-only`,htmlFor:`category-filter`,children:`Category`}),(0,U.jsx)(z_,{label:`Category`,emptyLabel:`All categories`,triggerId:`category-filter`,values:v,selected:a,onSelectedChange:o})]}):null,y.length>1?(0,U.jsxs)(Np,{children:[(0,U.jsx)(Fp,{className:`sr-only`,htmlFor:`severity-filter`,children:`Reported severity`}),(0,U.jsx)(z_,{label:`Reported severity`,emptyLabel:`All reported severity values`,triggerId:`severity-filter`,values:y,selected:s,onSelectedChange:c})]}):null,T.length>1?(0,U.jsxs)(Np,{children:[(0,U.jsx)(Fp,{className:`sr-only`,htmlFor:`notification-filter`,children:`Notification`}),(0,U.jsx)(z_,{label:`Notification`,emptyLabel:`All notification options`,triggerId:`notification-filter`,values:T,selected:l,formatValue:dg,onSelectedChange:u})]}):null,(0,U.jsx)(Tp,{type:`button`,variant:`ghost`,className:`alert-review-filter-clear`,onClick:E,disabled:!w,children:`Clear filters`})]})}),w?(0,U.jsx)(Bg,{className:`alert-review-filter-footer`,children:(0,U.jsxs)(`span`,{children:[b.length,` of `,e.length,` assignments match`]})}):null]}),w&&b.length===0?(0,U.jsxs)(`p`,{className:`results-no-match`,role:`status`,"aria-live":`polite`,children:[`No alerts match the current search and filters.`,` `,(0,U.jsx)(Tp,{type:`button`,variant:`ghost`,onClick:E,children:`Clear filters`})]}):null,(0,U.jsxs)(j_,{value:t,onValueChange:e=>{(e===`by-scope`||e===`by-alert`)&&n(e)},className:`alert-review-tabs`,children:[(0,U.jsxs)(N_,{variant:`line`,className:`alert-review-tabs-list`,"aria-label":`Alert review view`,children:[(0,U.jsx)(P_,{value:`by-scope`,children:`By scope`}),(0,U.jsx)(P_,{value:`by-alert`,children:`By alert`})]}),(0,U.jsxs)(F_,{value:`by-scope`,children:[(0,U.jsx)(`p`,{className:`alert-review-view-heading`,children:`What alerts are configured for each concrete scope?`}),(0,U.jsx)(x_,{collections:S,expandedAssignmentIds:p,onAssignmentExpandedChange:(e,t)=>m(n=>L_(n,e,t))})]}),(0,U.jsxs)(F_,{value:`by-alert`,children:[(0,U.jsx)(`p`,{className:`alert-review-view-heading`,children:`Which alert assignments are configured in each category?`}),(0,U.jsx)(C_,{categories:C,expandedAssignmentIds:h,onAssignmentExpandedChange:(e,t)=>g(n=>L_(n,e,t))})]})]})]})})}function W_({...e}){return(0,U.jsx)(yr,{"data-slot":`collapsible`,...e})}function G_({...e}){return(0,U.jsx)(mr,{"data-slot":`collapsible-trigger`,...e})}function K_({...e}){return(0,U.jsx)(gr,{"data-slot":`collapsible-content`,...e})}function q_(e){let t=new Date(e);return Number.isNaN(t.getTime())?e:new Intl.DateTimeFormat(void 0,{dateStyle:`medium`,timeStyle:`short`,timeZone:`UTC`}).format(t)}function J_({headingRef:e,run:t,latestRunId:n=t.id,runs:r=[t],onChangeConnection:i,onViewRun:a=()=>void 0,onReturnToLatest:o=()=>void 0,onDownload:s=()=>void 0}){let[c,l]=(0,_.useState)(`by-alert`),u=t.id!==n,d=r.filter(e=>e.id!==n);return(0,U.jsxs)(`section`,{className:`shell-panel results-panel results-panel-enter`,"aria-labelledby":`results-heading`,children:[(0,U.jsxs)(`div`,{className:`results-header`,children:[(0,U.jsx)(`h1`,{ref:e,id:`results-heading`,tabIndex:-1,children:u?`Viewing previous run`:`Enabled alerts`}),(0,U.jsx)(Tp,{type:`button`,variant:`ghost`,onClick:i,children:`Change connection`})]}),(0,U.jsxs)(`div`,{className:`results-run-context`,children:[u?(0,U.jsxs)(Dp,{className:`historical-run-notice`,children:[(0,U.jsx)(Op,{children:`Viewing previous run`}),(0,U.jsxs)(kp,{children:[`Cluster: `,t.cluster.name,` · Fetched:`,` `,(0,U.jsx)(`time`,{dateTime:t.fetchedAt,children:q_(t.fetchedAt)})]})]}):null,(0,U.jsxs)(`div`,{className:`results-action-row`,children:[u?(0,U.jsx)(Tp,{type:`button`,variant:`ghost`,onClick:o,children:`Return to latest results`}):null,(0,U.jsxs)(`div`,{className:`results-download-actions`,children:[(0,U.jsx)(Tp,{type:`button`,onClick:()=>s(`csv`),children:`Download all as CSV`}),(0,U.jsx)(Tp,{type:`button`,variant:`outline`,onClick:()=>s(`json`),children:`Download all as JSON`})]})]})]}),t.enabledAlertCount===0?(0,U.jsxs)(`div`,{className:`results-empty`,children:[(0,U.jsx)(`p`,{children:`No enabled alerts found`}),(0,U.jsx)(Tp,{type:`button`,variant:`outline`,onClick:i,children:`Change connection`})]}):(0,U.jsx)(U_,{alerts:t.alerts,tab:c,onTabChange:l},t.id),d.length===0?null:(0,U.jsxs)(W_,{className:`previous-runs`,children:[(0,U.jsx)(G_,{asChild:!0,children:(0,U.jsx)(Tp,{type:`button`,variant:`outline`,className:`previous-runs-trigger`,children:`Previous runs`})}),(0,U.jsx)(K_,{className:`previous-runs-content`,children:(0,U.jsx)(`ul`,{children:d.map(e=>(0,U.jsxs)(`li`,{children:[(0,U.jsxs)(`span`,{children:[(0,U.jsx)(`strong`,{children:e.cluster.name}),(0,U.jsx)(`time`,{dateTime:e.fetchedAt,children:q_(e.fetchedAt)}),(0,U.jsxs)(`span`,{children:[e.enabledAlertCount,` enabled`,` `,e.enabledAlertCount===1?`alert`:`alerts`]})]}),(0,U.jsx)(Tp,{type:`button`,variant:`ghost`,onClick:()=>a(e.id),children:`View results`})]},e.id))})})]})]})}function Y_(e,t){return`/api/extractions/runs/${encodeURIComponent(e)}/download/${t}`}var X_=(e,t)=>{let n=document.createElement(`a`);n.href=Y_(e,t),n.click()},Z_=`alert-inventory.theme`;function Q_(){return window.matchMedia?.(`(prefers-color-scheme: dark)`).matches?`dark`:`light`}function $_(){try{let e=window.localStorage.getItem(Z_);return e===`light`||e===`dark`?e:Q_()}catch{return Q_()}}function ev(e){document.documentElement.dataset.theme=e,document.documentElement.style.colorScheme=e}function tv(){let[e,t]=(0,_.useState)($_);return(0,_.useEffect)(()=>{ev(e)},[e]),{theme:e,toggleTheme:(0,_.useCallback)(()=>{let n=e===`light`?`dark`:`light`;try{window.localStorage.setItem(Z_,n)}catch{}ev(n),t(n)},[e])}}var nv=new Qh,rv={light:`Light`,dark:`Dark`};function iv(){let{theme:e,toggleTheme:t}=tv(),n=e===`light`?`dark`:`light`,r=`Theme: ${rv[e]}. Switch to ${n} theme`;return(0,U.jsx)(Tp,{type:`button`,variant:`outline`,size:`icon`,className:`app-theme-toggle`,"aria-label":r,title:r,onClick:t,children:(0,U.jsx)(e===`dark`?M:F,{"data-icon":`inline-start`,"data-theme-icon":e===`dark`?`moon`:`sun`,"aria-hidden":`true`})})}function av({state:e,completedRuns:t=[],latestRunId:n=``,credentialValidator:r=nh,initialSavedToken:i,onValidated:a=()=>void 0,fetchWorkflow:o,onChangeConnection:s=()=>void 0,onViewRun:c=()=>void 0,onReturnToLatest:l=()=>void 0,onDownload:u=()=>void 0}){let d=(0,_.useRef)(null),f=(0,_.useRef)(null);return(0,_.useEffect)(()=>{let t=e.kind===`results`?`${e.kind}:${e.run.id}`:e.kind;e.kind===`results`&&f.current!==null&&f.current!==t&&d.current?.focus(),f.current=t},[e]),e.kind===`credentials`?(0,U.jsx)(Ch,{allowTokenSaving:!0,fetchWorkflow:o,headingRef:d,initialCluster:e.initialCluster,initialSavedToken:e.tokenError?void 0:i,initialTokenError:e.tokenError,savedTokenNeedsReplacement:e.savedTokenNeedsReplacement,onValidated:a,validator:r}):(0,U.jsx)(J_,{headingRef:d,run:e.run,latestRunId:n,runs:t,onChangeConnection:()=>s(e.run),onViewRun:c,onReturnToLatest:l,onDownload:u})}function ov(e,t){let n=[...t];e.kind===`results`&&!n.some(t=>t.id===e.run.id)&&n.unshift(e.run),n.sort((e,t)=>t.fetchedAt.localeCompare(e.fetchedAt));let r=n[0];return{runs:n,latestRunId:r?.id??``,state:r?{kind:`results`,run:r}:e}}function sv({credentialValidator:e=rh,initialSavedToken:t,onFetchingStart:n,extractionAttemptAdapter:r=nv,onRunComplete:i,initialState:a=th,initialCompletedRuns:o=[],runHistoryAdapter:s,runDownloader:c=X_}){let[l]=(0,_.useState)(()=>ov(a,o)),[u,d]=(0,_.useState)(l.state),[f,p]=(0,_.useState)(l.runs),[m,h]=(0,_.useState)(l.latestRunId),[g,v]=(0,_.useState)(t),y=s??(o.length===0&&r instanceof Qh?r:void 0),b=Ah(r,{onCancelled:()=>v(void 0),onComplete:e=>{p(t=>[e,...t.filter(t=>t.id!==e.id)]),h(e.id),d({kind:`results`,run:e}),i?.(e)},onInvalidAccess:(e,t)=>{v(void 0),d({kind:`credentials`,initialCluster:e.cluster,tokenError:e.credentialSource===`saved-token`?`The saved token is invalid or expired. Enter a replacement token; it has not been deleted.`:t,savedTokenNeedsReplacement:e.credentialSource===`saved-token`})}});return(0,_.useEffect)(()=>{if(o.length>0||!y)return;let e=new AbortController,t=!0;return y.listCompletedRuns(e.signal).then(e=>{if(!t||e===null||e.runs.length===0)return;let n=e.runs.find(t=>t.id===e.latestRunId);n&&(p(e.runs),h(n.id),d({kind:`results`,run:n}))}),()=>{t=!1,e.abort()}},[y,o.length]),(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(`a`,{className:`skip-link`,href:`#main-content`,children:`Skip to content`}),(0,U.jsx)(`header`,{className:H(`app-header`,u.kind===`results`&&`app-header-results`),"aria-label":`Alert Inventory`,children:(0,U.jsxs)(`div`,{className:`app-header-content`,children:[(0,U.jsx)(`strong`,{className:`app-header-title`,children:`Alert Inventory`}),(0,U.jsx)(iv,{})]})}),(0,U.jsx)(`main`,{id:`main-content`,className:H(`main-content`,u.kind===`results`&&`main-content-results`),children:(0,U.jsx)(av,{completedRuns:f,latestRunId:m,credentialValidator:e,initialSavedToken:u.kind===`credentials`&&u.tokenError?void 0:g,onValidated:e=>{v(void 0),n?.(e),b.start(e)},fetchWorkflow:b,onChangeConnection:e=>{d({kind:`credentials`,initialCluster:e.cluster})},onViewRun:e=>{let t=f.find(t=>t.id===e);t&&d({kind:`results`,run:t})},onReturnToLatest:()=>{let e=f.find(e=>e.id===m);e&&d({kind:`results`,run:e})},onDownload:e=>{u.kind===`results`&&c(u.run.id,e)},state:u})})]})}var cv=e=>fetch(e);function lv(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function uv(e=cv){try{let t=await e(`/api/credentials/saved-token`);if(!t.ok)return;let n=await t.json();if(!lv(n)||!lv(n.savedToken))return;let r=n.savedToken.cluster;if(!lv(r))return;let i=Xm.find(e=>e.name===r.name&&e.origin===r.origin);return i?{cluster:i}:void 0}catch{return}}var dv=document.getElementById(`root`);if(!dv)throw Error(`Application root element was not found`);var fv=(0,v.createRoot)(dv),pv=e=>{fv.render((0,U.jsx)(_.StrictMode,{children:e}))};uv().then(e=>{pv((0,U.jsx)(sv,{initialSavedToken:e,initialState:{kind:`credentials`}}))}); \ No newline at end of file diff --git a/transition/alert-inventory/static/index.html b/transition/alert-inventory/static/index.html new file mode 100644 index 0000000..e3d46c1 --- /dev/null +++ b/transition/alert-inventory/static/index.html @@ -0,0 +1,32 @@ + + + + + + Alert Inventory + + + + + +
+ + diff --git a/transition/alert-inventory/token.json b/transition/alert-inventory/token.json new file mode 100644 index 0000000..636e827 --- /dev/null +++ b/transition/alert-inventory/token.json @@ -0,0 +1,6 @@ +{ + "base_url": "CENTRAL_BASE_URL", + "token": { + "access_token": "REPLACE_WITH_YOUR_CLASSIC_CENTRAL_ACCESS_TOKEN" + } +} diff --git a/transition/alert-inventory/token.json.example b/transition/alert-inventory/token.json.example new file mode 100644 index 0000000..636e827 --- /dev/null +++ b/transition/alert-inventory/token.json.example @@ -0,0 +1,6 @@ +{ + "base_url": "CENTRAL_BASE_URL", + "token": { + "access_token": "REPLACE_WITH_YOUR_CLASSIC_CENTRAL_ACCESS_TOKEN" + } +}