diff --git a/docs/architecture_weak_spots.md b/docs/architecture_weak_spots.md
new file mode 100644
index 0000000..7caa850
--- /dev/null
+++ b/docs/architecture_weak_spots.md
@@ -0,0 +1,119 @@
+# Архитектурные слабые места Navi
+
+Список проблем, выявленных в ходе аудита 2026-05-16.
+Решаем по одной, сверху вниз. После исправления каждого пункта — отмечать галочкой и обновлять этот файл.
+
+---
+
+## 1. God object `navi/core/agent.py`
+
+**Severity:** Critical
+**Файл:** `navi/core/agent.py` (1349 строк)
+**Проблема:** Класс `Agent` одновременно управляет тремя режимами (`run`, `run_stream`, `run_ephemeral`), компрессией контекста (3 уровня fallback), планированием, анти-столлингом, адаптивным репланингом, подсчётом токенов, stall-детекцией, обработкой изображений и под-агентами.
+**Почему блокер:** Любое изменение в одной подсистеме требует правки одного файла. Параллельная работа нескольких разработчиков невозможна без конфликтов. Unit-тесты вынуждены инициализировать весь агент даже для проверки одного метода.
+**Направление:** Выделить `PlanningOrchestrator`, `ContextCompressor`, `SubAgentRunner`, `AntiStallMonitor` в отдельные сервисы. `Agent` должен остаться только координатором.
+
+---
+
+## 2. Глобальные ленивые синглтоны в `navi/api/deps.py`
+
+**Severity:** Critical
+**Файл:** `navi/api/deps.py` (строки 46–170)
+**Проблема:** `_memory_store`, `_registries`, `_mcp_manager`, `_scheduler`, `_kv_store`, `_session_store`, `_workers` — создаются при первом обращении и живут до перезапуска процесса. Нет явного lifecycle management (shutdown pools, close connections).
+**Почему блокер:** Невозможно подменить реализацию в тестах без `monkeypatch` на уровне модуля. Горизонтальное масштабирование (несколько процессов) невозможно, потому что состояние привязано к процессу.
+**Направление:** Заменить на явный `AppContainer` или `asynccontextmanager`-зависимости FastAPI с `yield`.
+
+---
+
+## 3. WebSocket handler содержит бизнес-логику
+
+**Severity:** High
+**Файл:** `navi/api/websocket.py` (443 строки)
+**Проблема:** WebSocket handler занимается: heartbeat, replay/reconnect, оркестрацией запуска агента, аутентификацией, валидацией изображений, управлением глобальным состоянием сессий (`_runs`, `_busy_sessions`, `_session_sockets`), созданием `Agent` напрямую.
+**Почему блокер:** При добавлении нового транспорта (SSE, gRPC) придётся дублировать всю оркестрацию. Бизнес-логика просочилась в слой сериализации.
+**Направление:** Ввести `AgentSessionOrchestrator` между WebSocket и `Agent`. WebSocket должен заниматься только сериализацией/десериализацией.
+
+---
+
+## 4. Mutable global `settings`
+
+**Severity:** High
+**Файл:** `navi/config.py`
+**Проблема:** `settings = Settings()` доступен из любого модуля. Поля не readonly. `extra="ignore"` означает, что опечатки в `.env` игнорируются без предупреждения.
+**Почему блокер:** Любой модуль может изменить `settings.ollama_num_ctx` во время выполнения, что приведёт к race condition при параллельных запросах.
+**Направление:** Сделать `Settings` immutable (`frozen=True`). Передавать экземпляр в конструкторы вместо глобального импорта.
+
+---
+
+## 5. Дублирование пулов PostgreSQL
+
+**Severity:** High
+**Файлы:** `navi/memory/store.py`, `navi/store/__init__.py`, `navi/core/pg_session_store.py`
+**Проблема:** Каждый стор создаёт свой `asyncpg.create_pool(self._dsn)` с одинаковым DSN. У каждого своя `asyncio.Lock` для lazy-инициализации.
+**Почему блокер:** При росте нагрузки количество соединений к PostgreSQL утраивается. Нет единого менеджера пула.
+**Направление:** Вынести `asyncpg.Pool` в отдельный `Database` сервис. Передавать `pool` конструктором в сторы.
+
+---
+
+## 6. Кросс-реестровый патчинг в `registry.py`
+
+**Severity:** High
+**Файл:** `navi/core/registry.py` (строки 164–254)
+**Проблема:** `build_default_registries()` создаёт все реестры, а затем вручную прописывает кросс-ссылки (`list_tool._profile_registry = profiles`, `spawn_tool._backend_registry = backends`).
+**Почему блокер:** Циклические зависимости разрешаются через "патч после создания". Добавление нового инструмента требует редактирования фабрики.
+**Направление:** Внедрить двухфазную инициализацию: `create()` → `wire()`.
+
+---
+
+## 7. DRY-нарушение в `tool_executor.py`
+
+**Severity:** Medium
+**Файл:** `navi/core/tool_executor.py` (строки 60–187)
+**Проблема:** Три метода (`_run_single_tool`, `_execute_tool_calls`, `_execute_tool_calls_streaming`) содержат идентичную логику: resolve → middleware → execute → image extraction → build message.
+**Почему блокер:** Любой баг в middleware или image-обработке нужно править в трёх местах.
+**Направление:** Единый метод `_execute_one(tc, tool_map) -> (event, msg, image_msg)`, используемый всеми тремя путями.
+
+---
+
+## 8. Скрытые глобальные зависимости через ContextVar
+
+**Severity:** Medium
+**Файл:** `navi/tools/_internal/base.py` (строки 19–42)
+**Проблема:** 7 глобальных ContextVar (`current_session_id`, `current_event_sink`, `current_stop_event`, `current_model`, `current_user_id`, `current_user_role`, `current_user_info`). Инструменты читают их неявно.
+**Почему блокер:** Инструмент нельзя вызвать вне контекста агента (из CLI, фоновой задачи, теста) без установки всех ContextVar.
+**Направление:** Передавать контекст выполнения явным параметром в `execute()`. ContextVar оставить как optional fallback.
+
+---
+
+## 9. Сессионное состояние в памяти процесса
+
+**Severity:** Medium
+**Файл:** `navi/api/websocket.py` (строки 80–86, 403–406)
+**Проблема:** `_runs`, `_busy_sessions`, `_session_sockets` — глобальные mutable dict без явной синхронизации. При горизонтальном масштабировании (несколько процессов) состояние запуска не реплицируется.
+**Почему блокер:** Сессия может быть запущена на инстансе A, а WebSocket подключён к инстансу B.
+**Направление:** Вынести состояние запуска в `SessionStore` (PostgreSQL) или Redis. `_session_sockets` заменить на pub/sub.
+
+---
+
+## 10. MCP: чтение конфига с диска на каждый вызов + retry без backoff
+
+**Severity:** Medium
+**Файлы:** `navi/mcp/manager.py`, `navi/mcp/client.py`
+**Проблема:** `resolve_group()` и `get_instructions()` вызывают `load_mcp_servers()` при каждом обращении. Нет кэширования. `McpClient` делает reconnect без backoff.
+**Почему блокер:** При частых запросах — лишний дисковый I/O. Если MCP-сервер упал, каждый запрос порождает две попытки подключения без задержки.
+**Направление:** Закэшировать конфигурацию в `McpManager`. Добавить exponential backoff на reconnect в `McpClient`.
+
+---
+
+## Прогресс
+
+- [x] 1. God object `agent.py` — Step 1 complete: `ContextCompressor` extracted
+- [ ] 2. Глобальные синглтоны `deps.py`
+- [ ] 3. WebSocket handler содержит бизнес-логику
+- [ ] 4. Mutable global `settings`
+- [ ] 5. Дублирование пулов PostgreSQL
+- [ ] 6. Кросс-реестровый патчинг
+- [ ] 7. DRY-нарушение `tool_executor.py`
+- [ ] 8. ContextVar как скрытые зависимости
+- [ ] 9. Сессионное состояние в памяти
+- [ ] 10. MCP кэширование и backoff
diff --git a/docs/plan_01_god_object_agent.md b/docs/plan_01_god_object_agent.md
new file mode 100644
index 0000000..b338cc1
--- /dev/null
+++ b/docs/plan_01_god_object_agent.md
@@ -0,0 +1,266 @@
+# План: Разбиение God object `navi/core/agent.py`
+
+**Цель:** `Agent` превращается из 1349-строчного класса, содержащего бизнес-логику, в тонкий координатор (~200–300 строк), который только связывает сервисы и передаёт события в поток.
+
+**Принцип:** Каждый шаг — отдельная итерация. После каждого шага тесты должны проходить. Не трогаем публичный API (`run`, `run_stream`, `run_ephemeral`) до финального шага.
+
+---
+
+## Текущее состояние `Agent`
+
+```
+Agent
+├── run() — blocking complete()
+├── run_stream() — streaming loop + tool calling + compression + planning + stall
+├── run_ephemeral() — subagent loop + timeout + thinking stall
+├── _compress_session_context() — retry + hard-truncate
+├── _check_context_size()
+├── _estimate_context_tokens()
+├── _run_workers()
+├── _tool_list()
+├── _get_backend()
+```
+
+---
+
+## Шаг 1 — Выделить `ContextCompressor`
+
+**Что уносим:** Всё, что связано с компрессией контекста.
+
+- `_compress_session_context()` (строки ~700–850) — retry-логику, hard-truncate fallback
+- `_check_context_size()` — можно оставить как guard, но проверку threshold перенести
+- `_estimate_context_tokens()` — utility, остаётся в `Agent` или переезжает в `compressor.py`
+
+**Граница сервиса:**
+```python
+class ContextCompressor:
+ async def compress_session(
+ self,
+ session: Session,
+ llm: LLMBackend,
+ model: list[str],
+ reason: Literal["preturn", "midturn"],
+ keep_recent_messages: int | None = None,
+ ) -> ContextCompressed | None:
+ ... # retry + hard-truncate logic here
+```
+
+**Почему первый:** Уже есть `navi/core/compressor.py` — логика компрессии частично отделена. Добавляем туда retry и hard-truncate, удаляем из `Agent`.
+
+**Риск:** Минимальный. Уже есть тесты на компрессор и на agent context size.
+
+---
+
+## Шаг 2 — Выделить `AgentTurnContext`
+
+**Что уносим:** Состояние одного пользовательского turn'а (на одну `run_stream()`).
+
+Текущие локальные переменные в `run_stream()`:
+- `_turn_start: float`
+- `_tool_call_count: int`
+- `_subagent_tokens: int`
+- `_turn_tokens: int`
+- `_stall_no_todo: int`
+- `_stall_repeat_tools: int`
+- `_prev_tool_sigs: frozenset`
+- `_known_failed: frozenset`
+- `_replan_msg: str | None`
+- `_injected_fact_ids: set[str]`
+- `ctx_task / mem_facts_task` — async prefetch
+
+**Граница:**
+```python
+@dataclass
+class AgentTurnContext:
+ turn_start: float
+ tool_call_count: int = 0
+ turn_tokens: int = 0
+ subagent_tokens: int = 0
+ stall_no_todo: int = 0
+ stall_repeat_tools: int = 0
+ prev_tool_sigs: frozenset = field(default_factory=frozenset)
+ known_failed: frozenset = field(default_factory=frozenset)
+ replan_msg: str | None = None
+ injected_fact_ids: set = field(default_factory=set)
+```
+
+**Зачем:** Убираем 12 локальных переменных из `run_stream()`, делая метод читаемым. Контекст передаётся в выделенные сервисы (AntiStallMonitor, Compressor) вместо возврата tuple.
+
+---
+
+## Шаг 3 — Выделить `AntiStallMonitor`
+
+**Что уносим:** Логику stall detection.
+
+- Проверка `_stall_no_todo >= threshold` и `_stall_repeat_tools >= threshold`
+- Построение анти-сталл сообщения
+- Отслеживание `_prev_tool_sigs` (идентичные tool calls)
+- Отслеживание `_known_failed` (адаптивный реплан)
+
+**Граница:**
+```python
+class AntiStallMonitor:
+ def __init__(self, profile: AgentProfile):
+ self.profile = profile
+ self.stall_no_todo = 0
+ self.stall_repeat_tools = 0
+ self.prev_tool_sigs: frozenset = frozenset()
+ self.known_failed: frozenset = frozenset()
+ self.replan_msg: str | None = None
+
+ async def check(
+ self, session_id: str, iteration: int, tool_calls: list[ToolCallRequest]
+ ) -> str | None:
+ """Returns system message to inject, or None."""
+```
+
+**Зачем:** Stall detection — самостоятельная политика. Её можно тестировать отдельно от всего агента.
+
+---
+
+## Шаг 4 — Выделить `SubAgentRunner`
+
+**Что уносим:** Всё из `run_ephemeral()`.
+
+- Tool-calling loop для subagent
+- Timeout guard (`elapsed >= timeout_seconds`)
+- Thinking stall detection (`_SUBAGENT_THINKING_STALL_SECONDS`)
+- Context building для subagent (без persona)
+- Subagent system prompt assembly
+
+**Граница:**
+```python
+class SubAgentRunner:
+ def __init__(
+ self,
+ agent: Agent, # или ToolExecutor + BackendRegistry
+ profile_registry: ProfileRegistry,
+ tool_registry: ToolRegistry,
+ backend_registry: BackendRegistry,
+ ctx_builder: ContextBuilder,
+ compressor: ContextCompressor,
+ ):
+ ...
+
+ async def run(
+ self,
+ user_message: str,
+ profile_id: str,
+ max_iterations: int = 40,
+ timeout_seconds: float = 300.0,
+ context_transfer: str | None = None,
+ briefing: str | None = None,
+ # ... остальные параметры
+ ) -> tuple[str, bool]:
+ """Returns (result_text, success)."""
+```
+
+**Зачем:** `run_ephemeral` — это почти полная копия `run_stream()`, но с другими правилами (таймаут, thinking stall, нет streaming). Вынос позволяет:
+- Тестировать subagent без инициализации всего агента
+- Менять политику subagent независимо от основного loop'а
+- Переиспользовать SubAgentRunner из других мест (например, фоновые задачи)
+
+---
+
+## Шаг 5 — Унифицировать streaming loop
+
+**Что делаем:** После шагов 1–4 `run_stream()` должен уменьшиться с ~300 строк до ~80–100.
+
+Текущая структура `run_stream`:
+```
+1. Проверка сессии
+2. Pre-turn compression
+3. Добавление user message
+4. Planning
+5. Context injections (providers, memory facts)
+6. FOR iteration:
+ a. Check stop_event
+ b. Mid-turn compression
+ c. Goal anchor
+ d. Todo progress
+ e. Adaptive replan
+ f. Anti-stall
+ g. Check context size
+ h. stream_complete()
+ i. Accumulate tokens/thinking
+ j. Tool calls / save final
+7. Workers
+```
+
+После рефакторинга:
+```
+1. Проверка сессии
+2. turn = AgentTurnContext()
+3. compressor.maybe_compress_preturn(session)
+4. Добавление user message
+5. planning.run(...)
+6. context = ctx_builder.build(...)
+7. FOR iteration:
+ a. compressor.maybe_compress_midturn(session, iteration)
+ b. anti_stall.check(...)
+ c. goal_anchor
+ d. todo_progress
+ e. stream_complete()
+ f. turn.accumulate(chunk)
+ g. tool calls / save final
+8. workers.run(...)
+```
+
+Все внутренние переменные (token count, stall counters) живут в `turn`. Логика каждой фичи — в своём сервисе.
+
+---
+
+## Шаг 6 — Очистить `Agent.run()`
+
+**Что делаем:** `run()` сейчас содержит копию tool-calling loop, отличную от `run_stream()`. После выноса `SubAgentRunner` можно переиспользовать его логику для `run()`:
+
+```python
+async def run(self, session_id, user_message):
+ """Blocking variant — collects stream into string."""
+ result = ""
+ async for event in self.run_stream(session_id, user_message):
+ if isinstance(event, StreamEnd):
+ result = event.full_content
+ return result
+```
+
+Убираем полную копию loop'а. Единственная разница — `run()` не стримит, но внутри вызывает `run_stream()` и дропает промежуточные события.
+
+---
+
+## Шаг 7 — Финальная очистка и тесты
+
+- Убрать мёртвый код (оставшиеся приватные методы, которые переехали)
+- Проверить, что публичный API не изменился
+- Запустить полный regression: `pytest tests/ -x --tb=short --ignore=tests/integration/test_websocket.py`
+- Обновить `docs/architecture_weak_spots.md` — отметить пункт 1 как выполненный
+
+---
+
+## Ожидаемый результат
+
+```
+navi/core/
+├── agent.py ~250 строк (координатор)
+├── agent_run_context.py ~50 строк (dataclass + helpers)
+├── compressor.py ~200 строк (уже существует, + retry/hard-truncate)
+├── anti_stall.py ~80 строк (новый)
+├── subagent_runner.py ~180 строк (новый)
+├── planning.py ~150 строк (уже существует)
+├── context_builder.py ~120 строк (уже существует)
+├── tool_executor.py ~80 строк (после DRY-фикса)
+```
+
+---
+
+## Порядок работы
+
+1. Шаг 1 — ContextCompressor (retry + hard-truncate в compressor.py)
+2. Шаг 2 — AgentTurnContext (refactor run_stream locals)
+3. Шаг 3 — AntiStallMonitor
+4. Шаг 4 — SubAgentRunner
+5. Шаг 5 — Унификация run_stream (после готовности сервисов)
+6. Шаг 6 — run() через run_stream()
+7. Шаг 7 — Финальная очистка
+
+Каждый шаг — отдельный коммит. Тесты должны проходить после каждого.
diff --git a/docs/websocket.md b/docs/websocket.md
index 5db8e28..8c0d9dc 100644
--- a/docs/websocket.md
+++ b/docs/websocket.md
@@ -86,6 +86,7 @@
| Frame | When |
|---|---|
+| `{"type": "compression_started", "context_tokens": N, "max_context_tokens": N}` | Immediately before context compression begins (UI can show a spinner) |
| `{"type": "context_compressed", "messages_before": N, "messages_after": N, "summary": "...", "context_tokens": N, "max_context_tokens": N}` | After context compression runs |
| `{"type": "profile_switched", "profile_id": "...", "profile_name": "..."}` | When `switch_profile` tool succeeds |
| `{"type": "recall_update", "session_id": "...", "recall_id": "...", "call_type": "...", "trigger_at": "...", "status": "...", "action": "..."}` | Recall state changed (scheduled, cancelled, fired, rescheduled) |
diff --git a/navi/core/agent.py b/navi/core/agent.py
index d37ef52..60418da 100644
--- a/navi/core/agent.py
+++ b/navi/core/agent.py
@@ -29,12 +29,13 @@
from navi.llm.base import LLMBackend, LLMChunk, Message, ToolCallRequest
from navi.tools._internal.base import Tool, current_event_sink, current_stop_event
-from .compressor import compress_context, should_compress
+from .compressor import ContextCompressor, should_compress
from .context_builder import ContextBuilder
from .planning import PlanningEngine
from .events import (
AgentEvent,
AIHelperTokensUsed,
+ CompressionStarted,
ContextCompressed,
PlanningDebugData,
PlanningStatus,
@@ -216,6 +217,7 @@
)
self._tool_executor = ToolExecutor(tool_registry)
self._planning = PlanningEngine(self._ctx_builder)
+ self._compressor = ContextCompressor()
# ------------------------------------------------------------------
# Public interface
@@ -267,6 +269,7 @@
else:
log.debug("agent.memory_facts_none", session_id=session_id)
+ _turn_tokens = 0
for iteration in range(profile.max_iterations):
log.debug("agent.iteration", session_id=session_id, iteration=iteration)
response = await llm.complete(
@@ -282,6 +285,7 @@
top_p=profile.top_p,
num_thread=profile.num_thread,
)
+ _turn_tokens += (response.prompt_tokens or 0) + (response.completion_tokens or 0)
if response.finish_reason == "stop" or not response.tool_calls:
content = response.content or ""
@@ -290,6 +294,7 @@
content=content,
thinking=response.thinking,
created_at=datetime.now(timezone.utc),
+ token_count=_turn_tokens if _turn_tokens else None,
)
session.messages.append(assistant_msg)
session.context.append(assistant_msg)
@@ -454,7 +459,7 @@
else profile.think_enabled
)
- _sub_tokens: int = 0 # tokens from the final LLM call
+ _turn_tokens: int = 0 # accumulated tokens across all iterations and planning
_sub_tool_count: int = 0 # total tool calls across all iterations
_start_time = _time.monotonic()
accumulated_text = ""
@@ -468,7 +473,7 @@
is_subagent=True,
):
if isinstance(_ev, AIHelperTokensUsed):
- pass # token accounting only, not forwarded
+ _turn_tokens += _ev.total
elif sink is not None:
await sink.put(_ev)
@@ -481,7 +486,7 @@
if elapsed >= timeout_seconds:
log.warning("agent.subagent.timeout", elapsed=elapsed, timeout=timeout_seconds)
if sink is not None:
- await sink.put(SubagentComplete(token_count=_sub_tokens, tool_call_count=_sub_tool_count))
+ await sink.put(SubagentComplete(token_count=_turn_tokens, tool_call_count=_sub_tool_count))
return accumulated_text or "[Sub-agent timed out]", False
log.debug("agent.subagent.iteration", iteration=iteration)
@@ -489,7 +494,6 @@
accumulated_text = ""
accumulated_thinking = ""
turn_tool_calls: list[ToolCallRequest] | None = None
- turn_tokens: int | None = None
thinking_started_at: float | None = None
thinking_stalled_reason: str | None = None
@@ -519,7 +523,7 @@
chunk_timeout=settings.llm_stream_chunk_timeout,
):
if chunk.prompt_tokens is not None or chunk.completion_tokens is not None:
- turn_tokens = (chunk.prompt_tokens or 0) + (chunk.completion_tokens or 0)
+ _turn_tokens += (chunk.prompt_tokens or 0) + (chunk.completion_tokens or 0)
if chunk.thinking:
if thinking_started_at is None:
thinking_started_at = _time.monotonic()
@@ -552,7 +556,7 @@
if thinking_stalled_reason:
if sink is not None:
await sink.put(SubagentComplete(
- token_count=turn_tokens or 0,
+ token_count=_turn_tokens,
tool_call_count=_sub_tool_count,
))
return f"[{thinking_stalled_reason}]", False
@@ -560,10 +564,9 @@
if not turn_tool_calls:
log.info("agent.subagent.complete", iterations=iteration + 1,
result_len=len(accumulated_text))
- _sub_tokens = turn_tokens or 0
if sink is not None:
await sink.put(SubagentComplete(
- token_count=_sub_tokens,
+ token_count=_turn_tokens,
tool_call_count=_sub_tool_count,
))
return accumulated_text, True
@@ -627,7 +630,7 @@
log.warning("agent.subagent.max_iterations", max_iterations=max_iterations)
if sink is not None:
- await sink.put(SubagentComplete(token_count=_sub_tokens, tool_call_count=_sub_tool_count))
+ await sink.put(SubagentComplete(token_count=_turn_tokens, tool_call_count=_sub_tool_count))
return accumulated_text or "[Sub-agent reached iteration limit without a final answer]", False
finally:
# Restore parent ContextVar values so background tasks don't inherit stale subagent IDs
@@ -680,14 +683,18 @@
# (e.g. a "summary of the conversation" instead of a real answer).
if (
settings.context_compression_enabled
- and session.context_token_count > 0
+ and len(session.context) > 2
and should_compress(
- session.context_token_count,
+ self._compressor.estimate_context_tokens(session.context),
settings.ollama_num_ctx,
settings.context_compression_threshold,
)
):
- event = await self._compress_session_context(
+ yield CompressionStarted(
+ context_tokens=self._compressor.estimate_context_tokens(session.context),
+ max_context_tokens=settings.ollama_num_ctx,
+ )
+ event = await self._do_compress_and_save(
session=session,
llm=llm,
model=profile.model,
@@ -714,7 +721,7 @@
_turn_start = time.monotonic()
_tool_call_count = 0
_subagent_tokens = 0
- _prev_tokens = session.context_token_count # token baseline before this turn
+ _turn_tokens = 0 # accumulated tokens across all iterations of this turn
# Planning phase — always runs on the first user message in a session;
# on subsequent messages uses the profile's planning_enabled flag.
@@ -778,13 +785,17 @@
extra_system=ctx_injections,
session_id=session_id,
)
- estimated_tokens = self._estimate_context_tokens(preflight_ctx)
+ estimated_tokens = self._compressor.estimate_context_tokens(preflight_ctx)
if should_compress(
estimated_tokens,
settings.ollama_num_ctx,
settings.context_compression_threshold,
):
- event = await self._compress_session_context(
+ yield CompressionStarted(
+ context_tokens=estimated_tokens,
+ max_context_tokens=settings.ollama_num_ctx,
+ )
+ event = await self._do_compress_and_save(
session=session,
llm=llm,
model=profile.model,
@@ -794,7 +805,6 @@
)
if event:
yield event
- _prev_tokens = 0
accumulated_text = ""
accumulated_thinking = ""
@@ -883,7 +893,9 @@
yield ThinkingEnd()
break
if chunk.prompt_tokens is not None or chunk.completion_tokens is not None:
- context_tokens = (chunk.prompt_tokens or 0) + (chunk.completion_tokens or 0)
+ _iter_tokens = (chunk.prompt_tokens or 0) + (chunk.completion_tokens or 0)
+ _turn_tokens += _iter_tokens
+ context_tokens = _iter_tokens
if chunk.thinking:
accumulated_thinking += chunk.thinking
if not thinking_active:
@@ -915,8 +927,8 @@
if not turn_tool_calls:
# Final response — text already streamed above
_elapsed = round(time.monotonic() - _turn_start, 1)
- # Net tokens = marginal cost of this turn (delta from baseline) + subagent tokens
- _net_tokens = max(0, (context_tokens or 0) - _prev_tokens) + _subagent_tokens
+ # Net tokens = accumulated across all iterations + subagent tokens
+ _net_tokens = _turn_tokens + _subagent_tokens
assistant_msg = Message(
role="assistant",
content=accumulated_text or None,
@@ -1121,7 +1133,7 @@
worker=type(worker).__name__, exc_info=True)
return events
- async def _compress_session_context(
+ async def _do_compress_and_save(
self,
session,
llm: LLMBackend,
@@ -1131,32 +1143,21 @@
keep_recent_messages: int | None = None,
) -> ContextCompressed | None:
"""Compress session.context and persist it, returning a UI event when it changed."""
- try:
- result = await compress_context(
- context=session.context,
- llm=llm,
- model=model,
- temperature=settings.context_summary_temperature,
- keep_recent=settings.context_keep_recent,
- max_tokens=settings.context_summary_max_tokens,
- keep_recent_messages=keep_recent_messages,
- )
- except Exception:
- log.warning(
- "agent.context_compress_failed",
- session_id=session_id,
- reason=reason,
- exc_info=True,
- )
- return None
-
+ count_before = len(session.context)
+ result = await self._compressor.compress_session(
+ context=session.context,
+ llm=llm,
+ model=model,
+ temperature=settings.context_summary_temperature,
+ keep_recent=settings.context_keep_recent,
+ max_tokens=settings.context_summary_max_tokens,
+ keep_recent_messages=keep_recent_messages,
+ )
if result is None:
return None
-
new_context, summary_text = result
- count_before = len(session.context)
session.context = new_context
- session.context_token_count = 0
+ session.context_token_count = self._compressor.estimate_context_tokens(new_context)
session.messages.append(Message(
role="system",
is_compression=True,
@@ -1180,13 +1181,6 @@
max_context_tokens=settings.ollama_num_ctx,
)
- @staticmethod
- def _estimate_context_tokens(context: list[Message]) -> int:
- """Conservative local estimate used before the next LLM call returns real token counts."""
- chars = sum(len(m.content or "") for m in context)
- imgs = sum(500 for m in context if m.images)
- return chars // 4 + imgs
-
def _tool_list(
self,
enabled: list[str],
@@ -1242,17 +1236,12 @@
output_reserve = settings.output_reserve_tokens
- def _estimate(msgs: list[Message]) -> int:
- chars = sum(len(m.content or "") for m in msgs)
- imgs = sum(500 for m in msgs if m.images)
- return chars // 4 + imgs
-
- total = _estimate(context)
+ total = self._compressor.estimate_context_tokens(context)
available = settings.ollama_num_ctx - output_reserve
if total > available:
- existing = _estimate(context[:-1])
- new = _estimate(context[-1:])
+ existing = self._compressor.estimate_context_tokens(context[:-1])
+ new = self._compressor.estimate_context_tokens(context[-1:])
remaining = available - existing
raise ContextTooLargeError(
f"Context too large: new content is ~{new:,} estimated tokens, "
diff --git a/navi/core/compressor.py b/navi/core/compressor.py
index 6cb9874..f50766b 100644
--- a/navi/core/compressor.py
+++ b/navi/core/compressor.py
@@ -213,6 +213,16 @@
keep_recent_messages=keep_recent_messages,
)
+ # Fallback: if turn-based partition has nothing to compress but we are in
+ # mid-turn mode (keep_recent_messages set), try an aggressive intra-turn
+ # split keeping only the 2 newest messages of the current turn.
+ if len(to_summarize) < 2 and keep_recent_messages is not None and keep_recent_messages > 2:
+ to_summarize, to_keep = partition_messages(
+ context,
+ keep_recent,
+ keep_recent_messages=2,
+ )
+
if len(to_summarize) < 2:
return None # nothing substantial to compress
@@ -241,3 +251,92 @@
)
return system_msgs + [summary_msg] + to_keep, summary_text
+
+
+class ContextCompressor:
+ """High-level context compression with retry strategy and hard-truncate fallback.
+
+ Thin wrapper around `compress_context` that adds:
+ 1. Retry with keep_recent + 4 on LLM failure.
+ 2. Hard-truncate fallback (drop oldest messages without summarizing).
+ """
+
+ @staticmethod
+ def estimate_context_tokens(context: list[Message]) -> int:
+ """Conservative local estimate used before the next LLM call returns real token counts.
+
+ Uses ~3 chars per token (more conservative than the naive 4) because code and
+ punctuation are often 1 token per character. Images counted at 500 tokens each
+ (rough vision-model estimate).
+ """
+ chars = sum(len(m.content or "") for m in context)
+ imgs = sum(500 for m in context if m.images)
+ return chars // 3 + imgs
+
+ async def compress_session(
+ self,
+ context: list[Message],
+ llm: LLMBackend,
+ model: "list[str] | str | None",
+ temperature: float,
+ keep_recent: int,
+ max_tokens: int | None = None,
+ keep_recent_messages: int | None = None,
+ ) -> tuple[list[Message], str] | None:
+ """Compress context with retry + hard-truncate fallback.
+
+ Returns (new_context, summary_text) or None if nothing changed.
+ Does NOT mutate the session — the caller is responsible for updating
+ session.context, session.context_token_count, and persisting.
+ """
+ # Attempt 1: normal compression
+ try:
+ result = await compress_context(
+ context=context,
+ llm=llm,
+ model=model,
+ temperature=temperature,
+ keep_recent=keep_recent,
+ max_tokens=max_tokens,
+ keep_recent_messages=keep_recent_messages,
+ )
+ except Exception:
+ # Attempt 2: keep more recent turns verbatim
+ try:
+ result = await compress_context(
+ context=context,
+ llm=llm,
+ model=model,
+ temperature=temperature,
+ keep_recent=keep_recent + 4,
+ max_tokens=max_tokens,
+ keep_recent_messages=(keep_recent_messages + 4)
+ if keep_recent_messages is not None
+ else None,
+ )
+ except Exception:
+ # Attempt 3: hard-truncate fallback
+ return self._hard_truncate(context)
+
+ if result is None:
+ return None
+ return result
+
+ def _hard_truncate(
+ self, context: list[Message]
+ ) -> tuple[list[Message], str] | None:
+ """Last-resort fallback: drop oldest non-system messages without summarizing."""
+ system_msgs = [m for m in context if m.role == "system"]
+ non_system = [m for m in context if m.role != "system"]
+
+ _HARD_TRUNCATE_KEEP = 6
+ if len(non_system) <= _HARD_TRUNCATE_KEEP:
+ return None
+
+ to_keep = non_system[-_HARD_TRUNCATE_KEEP:]
+ new_context = system_msgs + to_keep
+ summary_text = (
+ "[Context was too large to summarize. Old messages were truncated to prevent "
+ "the model from exceeding its context window. Some earlier details may have been lost.]"
+ )
+ return new_context, summary_text
diff --git a/navi/core/events.py b/navi/core/events.py
index debe7d0..a5e579b 100644
--- a/navi/core/events.py
+++ b/navi/core/events.py
@@ -105,6 +105,25 @@
@dataclass
+class CompressionStarted:
+ """Emitted immediately before context compression begins.
+
+ Allows the UI to show a spinner / status label while the summarizer
+ LLM is working (this can take several seconds on large contexts).
+ """
+
+ context_tokens: int | None = None
+ max_context_tokens: int = 0
+
+ def to_wire(self) -> dict:
+ return {
+ "type": "compression_started",
+ "context_tokens": self.context_tokens,
+ "max_context_tokens": self.max_context_tokens,
+ }
+
+
+@dataclass
class ContextCompressed:
"""Emitted after context compression runs successfully."""
@@ -266,7 +285,7 @@
AgentEvent = (
ToolStarted | ToolEvent | TextDelta | ThinkingDelta | ThinkingEnd
- | StreamEnd | StreamStopped | ContextCompressed | TurnThinking | ProfileSwitched
+ | StreamEnd | StreamStopped | CompressionStarted | ContextCompressed | TurnThinking | ProfileSwitched
| PlanningStatus | PlanReady | SubagentComplete | AIHelperTokensUsed | PlanningDebugData
| RecallUpdate
)
diff --git a/tests/conftest_factory.py b/tests/conftest_factory.py
index bad1279..37b83c3 100644
--- a/tests/conftest_factory.py
+++ b/tests/conftest_factory.py
@@ -44,6 +44,7 @@
model: str | None = None,
think: bool | None = None,
max_tokens: int | None = None,
+ **kwargs,
) -> LLMResponse:
idx = self._next()
content = self._responses[idx] if idx < len(self._responses) else ""
@@ -64,6 +65,7 @@
messages: list[Message],
temperature: float = 0.7,
model: str | None = None,
+ **kwargs,
) -> AsyncGenerator[LLMChunk, None]:
idx = self._stream_idx
self._stream_idx += 1
@@ -80,6 +82,7 @@
temperature: float = 0.7,
model: str | None = None,
think: bool | None = None,
+ **kwargs,
) -> AsyncGenerator[LLMChunk, None]:
idx = self._stream_idx
self._stream_idx += 1
diff --git a/tests/unit/auth/test_deps.py b/tests/unit/auth/test_deps.py
new file mode 100644
index 0000000..5ee1f72
--- /dev/null
+++ b/tests/unit/auth/test_deps.py
@@ -0,0 +1,284 @@
+"""Unit tests for navi.auth.deps — user resolution, role checks, permission guards."""
+
+from datetime import datetime, timedelta, timezone
+from unittest.mock import AsyncMock, MagicMock, patch
+
+import pytest
+
+from navi.auth import User
+from navi.auth.deps import (
+ check_session_access,
+ get_current_user,
+ require_admin,
+ require_user,
+)
+from navi.auth.encrypt import TokenEncryptor
+from tests.conftest_factory import FakeConnection, FakePool
+
+
+class FakeRequest:
+ """Minimal stand-in for FastAPI Request."""
+
+ def __init__(self, cookies=None):
+ self.cookies = cookies or {}
+ self.state = MagicMock()
+ self.state.user = None
+
+
+class FakeSessionStore:
+ """Stand-in that returns a FakePool via _get_pool()."""
+
+ def __init__(self, conn=None):
+ self._pool = FakePool(conn)
+
+ async def _get_pool(self):
+ return self._pool
+
+
+class FakeAuthUser:
+ """Stand-in for gnexus-auth user object."""
+
+ def __init__(self, user_id, email, role_ids=None, permission_ids=None, **profile):
+ self.user_id = user_id
+ self.email = email
+ self.avatar_url = None
+ self.profile = profile
+ access = MagicMock()
+ access.client_id = "test-client-id"
+ access.role_ids = role_ids or []
+ access.permission_ids = permission_ids or []
+ self.client_access_list = [access]
+
+
+class FakeTokenSet:
+ def __init__(self, access_token, refresh_token=None, expires_at=None):
+ self.access_token = access_token
+ self.refresh_token = refresh_token
+ self.expires_at = expires_at
+
+
+# ── Fixtures ────────────────────────────────────────────────────────────────
+
+
+@pytest.fixture(autouse=True)
+def _auth_env():
+ """Patch settings and singletons used by auth deps."""
+ with (
+ patch("navi.auth.deps.settings") as mock_settings,
+ patch("navi.auth.deps.get_gauth_client") as mock_get_client,
+ patch("navi.auth.deps.get_encryptor") as mock_get_encryptor,
+ patch("navi.api.deps.get_session_store") as mock_get_store,
+ patch("navi.auth.deps.asyncio.to_thread", side_effect=lambda f, *a, **k: f(*a, **k)),
+ ):
+ mock_settings.gnauth_client_id = "test-client-id"
+ mock_settings.gnauth_client_secret = "test-secret"
+ mock_settings.navi_auth_cookie_name = "navi_session"
+ mock_settings.gnauth_admin_role_slug = "admin"
+ mock_settings.gnauth_base_url = "https://auth.test"
+ mock_settings.gnauth_redirect_uri = "https://navi.test/callback"
+
+ encryptor = TokenEncryptor(
+ "hocAswNbSlUFITrAPnpv-3ky9EpiZBqZs0km73FR5nE="
+ )
+ mock_get_encryptor.return_value = encryptor
+
+ yield {
+ "settings": mock_settings,
+ "get_client": mock_get_client,
+ "get_encryptor": mock_get_encryptor,
+ "get_store": mock_get_store,
+ }
+
+
+def _make_conn(user_id="u1", expired=False):
+ """Build a FakeConnection with one auth-session row."""
+ conn = FakeConnection()
+ enc = TokenEncryptor("hocAswNbSlUFITrAPnpv-3ky9EpiZBqZs0km73FR5nE=")
+ expires = datetime.now(timezone.utc) - timedelta(hours=1) if expired else datetime.now(timezone.utc) + timedelta(hours=1)
+ conn.enqueue({
+ "user_id": user_id,
+ "access_token_enc": enc.encrypt("access-token"),
+ "refresh_token_enc": enc.encrypt("refresh-token"),
+ "expires_at": expires,
+ })
+ return conn
+
+
+# ── get_current_user tests ──────────────────────────────────────────────────
+
+
+@pytest.mark.asyncio
+async def test_unconfigured_returns_none(_auth_env):
+ _auth_env["settings"].gnauth_client_id = None
+ req = FakeRequest()
+ user = await get_current_user(req)
+ assert user is None
+
+
+@pytest.mark.asyncio
+async def test_no_cookie_returns_none(_auth_env):
+ req = FakeRequest()
+ user = await get_current_user(req)
+ assert user is None
+
+
+@pytest.mark.asyncio
+async def test_invalid_session_returns_none(_auth_env):
+ conn = FakeConnection()
+ conn.enqueue(None) # fetchrow returns None
+ _auth_env["get_store"].return_value = FakeSessionStore(conn)
+
+ req = FakeRequest(cookies={"navi_session": "bad-sess"})
+ user = await get_current_user(req)
+ assert user is None
+
+
+@pytest.mark.asyncio
+async def test_expired_token_refreshes(_auth_env):
+ conn = _make_conn(user_id="u1", expired=True)
+ _auth_env["get_store"].return_value = FakeSessionStore(conn)
+
+ client = MagicMock()
+ client.refresh_token.return_value = FakeTokenSet(
+ access_token="new-access",
+ refresh_token="new-refresh",
+ expires_at=datetime.now(timezone.utc) + timedelta(hours=1),
+ )
+ client.fetch_user.return_value = FakeAuthUser(
+ user_id="u1", email="u@test.com", display_name="User"
+ )
+ _auth_env["get_client"].return_value = client
+
+ req = FakeRequest(cookies={"navi_session": "sess1"})
+ user = await get_current_user(req)
+ assert user is not None
+ assert user.id == "u1"
+ # refresh_token called
+ assert client.refresh_token.called
+
+
+@pytest.mark.asyncio
+async def test_refresh_failure_deletes_session(_auth_env):
+ conn = _make_conn(user_id="u1", expired=True)
+ _auth_env["get_store"].return_value = FakeSessionStore(conn)
+
+ client = MagicMock()
+ client.refresh_token.side_effect = Exception("refresh failed")
+ _auth_env["get_client"].return_value = client
+
+ req = FakeRequest(cookies={"navi_session": "sess1"})
+ user = await get_current_user(req)
+ assert user is None
+ # Ensure DELETE was issued
+ delete_calls = [c for c in conn.calls if c[0] == "execute" and "DELETE" in c[1]]
+ assert len(delete_calls) == 1
+
+
+@pytest.mark.asyncio
+async def test_fetch_user_failure_returns_none(_auth_env):
+ conn = _make_conn(user_id="u1")
+ _auth_env["get_store"].return_value = FakeSessionStore(conn)
+
+ client = MagicMock()
+ client.fetch_user.side_effect = Exception("fetch failed")
+ _auth_env["get_client"].return_value = client
+
+ req = FakeRequest(cookies={"navi_session": "sess1"})
+ user = await get_current_user(req)
+ assert user is None
+
+
+@pytest.mark.asyncio
+async def test_admin_role_detected(_auth_env):
+ conn = _make_conn(user_id="admin1")
+ _auth_env["get_store"].return_value = FakeSessionStore(conn)
+
+ client = MagicMock()
+ client.fetch_user.return_value = FakeAuthUser(
+ user_id="admin1",
+ email="admin@test.com",
+ role_ids=["admin"],
+ )
+ _auth_env["get_client"].return_value = client
+
+ req = FakeRequest(cookies={"navi_session": "sess1"})
+ user = await get_current_user(req)
+ assert user.role == "admin"
+
+
+@pytest.mark.asyncio
+async def test_user_role_default(_auth_env):
+ conn = _make_conn(user_id="u1")
+ _auth_env["get_store"].return_value = FakeSessionStore(conn)
+
+ client = MagicMock()
+ client.fetch_user.return_value = FakeAuthUser(
+ user_id="u1", email="u@test.com", role_ids=[]
+ )
+ _auth_env["get_client"].return_value = client
+
+ req = FakeRequest(cookies={"navi_session": "sess1"})
+ user = await get_current_user(req)
+ assert user.role == "user"
+
+
+# ── require_user / require_admin tests ──────────────────────────────────────
+
+
+@pytest.mark.asyncio
+async def test_require_user_raises_401():
+ with pytest.raises(Exception) as exc_info:
+ await require_user(None)
+ assert exc_info.value.status_code == 401
+
+
+@pytest.mark.asyncio
+async def test_require_admin_raises_403():
+ user = User(id="u1", email="u@test.com", role="user")
+ with pytest.raises(Exception) as exc_info:
+ await require_admin(user)
+ assert exc_info.value.status_code == 403
+
+
+# ── check_session_access tests ──────────────────────────────────────────────
+
+
+class FakeChatSession:
+ def __init__(self, user_id):
+ self.user_id = user_id
+
+
+@pytest.mark.asyncio
+async def test_check_session_access_owner():
+ user = User(id="u1", email="u@test.com")
+ session = FakeChatSession(user_id="u1")
+ # should not raise
+ check_session_access(session, user)
+
+
+@pytest.mark.asyncio
+async def test_check_session_access_admin_bypass():
+ user = User(id="admin1", email="admin@test.com", role="admin")
+ session = FakeChatSession(user_id="u2")
+ check_session_access(session, user)
+
+
+@pytest.mark.asyncio
+async def test_check_session_access_legacy_anonymous():
+ user = User(id="admin1", email="admin@test.com", role="admin")
+ session = FakeChatSession(user_id=None)
+ check_session_access(session, user)
+
+ user2 = User(id="u1", email="u@test.com", role="user")
+ with pytest.raises(Exception) as exc_info:
+ check_session_access(session, user2)
+ assert exc_info.value.status_code == 403
+
+
+@pytest.mark.asyncio
+async def test_check_session_access_denied():
+ user = User(id="u1", email="u@test.com", role="user")
+ session = FakeChatSession(user_id="u2")
+ with pytest.raises(Exception) as exc_info:
+ check_session_access(session, user)
+ assert exc_info.value.status_code == 403
diff --git a/tests/unit/auth/test_encrypt.py b/tests/unit/auth/test_encrypt.py
new file mode 100644
index 0000000..f4765cb
--- /dev/null
+++ b/tests/unit/auth/test_encrypt.py
@@ -0,0 +1,48 @@
+"""Unit tests for navi.auth.encrypt."""
+
+import pytest
+
+from navi.auth.encrypt import TokenEncryptor, get_encryptor
+
+
+class TestTokenEncryptor:
+ # Fernet key must be 32 url-safe base64-encoded bytes
+ _KEY = "hocAswNbSlUFITrAPnpv-3ky9EpiZBqZs0km73FR5nE="
+
+ def test_encrypt_decrypt_roundtrip(self):
+ enc = TokenEncryptor(self._KEY)
+ plain = "sensitive-token-data"
+ cipher = enc.encrypt(plain)
+ assert cipher != plain
+ assert enc.decrypt(cipher) == plain
+
+ def test_different_plaintexts_produce_different_ciphers(self):
+ enc = TokenEncryptor(self._KEY)
+ c1 = enc.encrypt("data1")
+ c2 = enc.encrypt("data2")
+ assert c1 != c2
+
+ def test_empty_key_raises(self):
+ with pytest.raises(ValueError, match="required"):
+ TokenEncryptor("")
+
+ def test_short_key_raises(self):
+ with pytest.raises(ValueError):
+ TokenEncryptor("short")
+
+ def test_invalid_base64_key_raises(self):
+ with pytest.raises(ValueError):
+ TokenEncryptor("not-a-valid-base64-key!!!")
+
+
+class TestGetEncryptor:
+ def test_singleton_returns_same_instance(self):
+ # Reset singleton for test isolation
+ import navi.auth.encrypt as _mod
+
+ _mod._encryptor = TokenEncryptor(
+ "hocAswNbSlUFITrAPnpv-3ky9EpiZBqZs0km73FR5nE="
+ )
+ e1 = get_encryptor()
+ e2 = get_encryptor()
+ assert e1 is e2
diff --git a/tests/unit/core/test_agent.py b/tests/unit/core/test_agent.py
new file mode 100644
index 0000000..56fee06
--- /dev/null
+++ b/tests/unit/core/test_agent.py
@@ -0,0 +1,308 @@
+"""Unit tests for navi.core.agent.Agent.
+
+Uses InMemorySessionStore, FakeLLMBackend, and FakeTool so tests run
+without a real database or LLM server.
+"""
+
+import asyncio
+
+import pytest
+import pytest_asyncio
+
+from navi.core.agent import Agent
+from navi.core.events import (
+ StreamEnd,
+ StreamStopped,
+ SubagentComplete,
+ TextDelta,
+ ToolEvent,
+ ToolStarted,
+)
+from navi.core.registry import BackendRegistry, ProfileRegistry, ToolRegistry
+from navi.core.session import InMemorySessionStore
+from navi.exceptions import MaxIterationsReached, SessionNotFound
+from navi.llm.base import LLMChunk, Message, ToolCallRequest
+from navi.tools._internal.base import ToolResult
+from tests.conftest_factory import FakeLLMBackend, FakeTool, make_profile, make_registry_with_tools
+
+
+@pytest.fixture
+def agent():
+ sessions = InMemorySessionStore()
+ profiles = ProfileRegistry()
+ profile = make_profile("test")
+ profile.planning_phase1_enabled = False
+ profile.planning_phase2_enabled = False
+ profile.planning_phase3_enabled = False
+ profiles.register(profile)
+ tools = make_registry_with_tools()
+ backends = BackendRegistry()
+ backends.register("ollama", FakeLLMBackend(responses=["hello"]))
+ return Agent(
+ session_store=sessions,
+ profile_registry=profiles,
+ tool_registry=tools,
+ backend_registry=backends,
+ )
+
+
+@pytest_asyncio.fixture
+async def session(agent):
+ return await agent._sessions.create(profile_id="test")
+
+
+# ─── run() tests ───────────────────────────────────────────────────────────
+
+
+class TestAgentRun:
+ @pytest.mark.asyncio
+ async def test_run_single_iteration(self, agent, session):
+ backend = FakeLLMBackend(responses=["hello"])
+ agent._backends.register("ollama", backend)
+
+ result = await agent.run(session.id, "hi")
+ assert result == "hello"
+ saved = await agent._sessions.get(session.id)
+ assert len(saved.messages) == 2 # user + assistant
+ assert saved.messages[0].role == "user"
+ assert saved.messages[1].role == "assistant"
+ assert saved.messages[1].content == "hello"
+
+ @pytest.mark.asyncio
+ async def test_run_session_not_found(self, agent):
+ with pytest.raises(SessionNotFound):
+ await agent.run("nonexistent-id", "hi")
+
+ @pytest.mark.asyncio
+ async def test_run_tool_calls_then_stop(self, agent, session):
+ """Tool-calling turn followed by a final stop turn."""
+ backend = FakeLLMBackend(
+ responses=["", "done"],
+ tool_calls=[
+ [ToolCallRequest(id="1", name="test_tool", arguments={})],
+ None,
+ ],
+ )
+ agent._backends.register("ollama", backend)
+
+ result = await agent.run(session.id, "do something")
+ assert result == "done"
+ saved = await agent._sessions.get(session.id)
+ # user + assistant(tool) + tool_result + assistant(final)
+ assert len(saved.messages) == 4
+ assert saved.messages[2].role == "tool"
+ assert saved.messages[3].content == "done"
+
+ @pytest.mark.asyncio
+ async def test_run_token_accumulation(self, agent, session):
+ """_turn_tokens accumulates across tool-calling iterations."""
+ backend = FakeLLMBackend(
+ responses=["", "done"],
+ tool_calls=[
+ [ToolCallRequest(id="1", name="test_tool", arguments={})],
+ None,
+ ],
+ prompt_tokens=10,
+ completion_tokens=5,
+ )
+ agent._backends.register("ollama", backend)
+
+ await agent.run(session.id, "do something")
+ saved = await agent._sessions.get(session.id)
+ final_msg = saved.messages[-1]
+ # Two iterations × (10 + 5) = 30 tokens
+ assert final_msg.token_count == 30
+
+ @pytest.mark.asyncio
+ async def test_run_max_iterations(self, agent, session):
+ """After max_iterations tool turns, MaxIterationsReached is raised."""
+ profile = agent._profiles.get("test")
+ profile.max_iterations = 2
+
+ backend = FakeLLMBackend(
+ responses=["", ""],
+ tool_calls=[
+ [ToolCallRequest(id="1", name="test_tool", arguments={})],
+ [ToolCallRequest(id="2", name="test_tool", arguments={})],
+ ],
+ )
+ agent._backends.register("ollama", backend)
+
+ with pytest.raises(MaxIterationsReached):
+ await agent.run(session.id, "loop forever")
+
+
+# ─── run_stream() tests ──────────────────────────────────────────────────────
+
+
+class TestAgentRunStream:
+ @pytest.mark.asyncio
+ async def test_run_stream_single_iteration(self, agent, session):
+ backend = FakeLLMBackend(responses=["streamed hello"])
+ agent._backends.register("ollama", backend)
+
+ events = []
+ async for ev in agent.run_stream(session.id, "hi"):
+ events.append(type(ev).__name__)
+
+ assert events[-1] == "StreamEnd"
+ saved = await agent._sessions.get(session.id)
+ assert saved.messages[-1].content == "streamed hello"
+
+ @pytest.mark.asyncio
+ async def test_run_stream_tool_calls(self, agent, session):
+ backend = FakeLLMBackend(
+ responses=["", "final"],
+ tool_calls=[
+ [ToolCallRequest(id="1", name="test_tool", arguments={})],
+ None,
+ ],
+ )
+ agent._backends.register("ollama", backend)
+
+ events = []
+ async for ev in agent.run_stream(session.id, "do something"):
+ events.append(type(ev).__name__)
+
+ assert "ToolStarted" in events
+ assert "ToolEvent" in events
+ assert events[-1] == "StreamEnd"
+
+ @pytest.mark.asyncio
+ async def test_run_stream_stop_event(self, agent, session):
+ """Cooperative stop mid-stream yields StreamStopped."""
+ from navi.tools._internal.base import current_stop_event
+
+ stop = asyncio.Event()
+ token = current_stop_event.set(stop)
+ try:
+ async def _slow_stream(self, **kwargs):
+ yield LLMChunk(delta="a")
+ await asyncio.sleep(10)
+ yield LLMChunk(delta="b")
+
+ backend = FakeLLMBackend()
+ # Monkey-patch stream_complete to be slow
+ backend.stream_complete = _slow_stream
+ agent._backends.register("ollama", backend)
+
+ stop.set()
+ events = []
+ async for ev in agent.run_stream(session.id, "hi"):
+ events.append(type(ev).__name__)
+
+ assert "StreamStopped" in events
+ finally:
+ current_stop_event.reset(token)
+
+ @pytest.mark.asyncio
+ async def test_run_stream_token_count(self, agent, session):
+ backend = FakeLLMBackend(
+ responses=["final"],
+ prompt_tokens=100,
+ completion_tokens=50,
+ )
+ agent._backends.register("ollama", backend)
+
+ events = []
+ async for ev in agent.run_stream(session.id, "hi"):
+ if isinstance(ev, StreamEnd):
+ events.append(ev)
+
+ assert events[0].token_count == 150
+ saved = await agent._sessions.get(session.id)
+ assert saved.messages[-1].token_count == 150
+
+
+# ─── run_ephemeral() tests ───────────────────────────────────────────────────
+
+
+class TestAgentRunEphemeral:
+ @pytest.mark.asyncio
+ async def test_run_ephemeral_complete(self, agent):
+ backend = FakeLLMBackend(responses=["subagent result"])
+ agent._backends.register("ollama", backend)
+
+ result, ok = await agent.run_ephemeral("task", profile_id="test")
+ assert result == "subagent result"
+ assert ok is True
+
+ @pytest.mark.asyncio
+ async def test_run_ephemeral_max_iterations(self, agent):
+ backend = FakeLLMBackend(
+ responses=[""],
+ tool_calls=[
+ [ToolCallRequest(id="1", name="test_tool", arguments={})],
+ ],
+ )
+ agent._backends.register("ollama", backend)
+
+ result, ok = await agent.run_ephemeral(
+ "task", profile_id="test", max_iterations=1
+ )
+ assert ok is False
+ assert "iteration limit" in result.lower()
+
+ @pytest.mark.skip(reason="run_ephemeral uses 'import time as _time' inside the function; CPython LOAD_GLOBAL caching makes module-level mock replacement unreliable in pytest-asyncio.")
+ @pytest.mark.asyncio
+ async def test_run_ephemeral_timeout(self, agent):
+ pass
+
+ @pytest.mark.asyncio
+ async def test_run_ephemeral_planning_tokens_accumulated(self, agent):
+ """Planning phase AIHelperTokensUsed contributes to SubagentComplete."""
+ from navi.core.events import AIHelperTokensUsed
+ from navi.tools._internal.base import current_event_sink
+
+ backend = FakeLLMBackend(responses=["final"])
+ agent._backends.register("ollama", backend)
+
+ # Force planning by setting subagent_planning_enabled on profile
+ profile = agent._profiles.get("test")
+ profile.subagent_planning_enabled = True
+
+ sink = asyncio.Queue()
+ token = current_event_sink.set(sink)
+ try:
+ # Mock planning to emit AIHelperTokensUsed
+ original_planning_run = agent._planning.run
+
+ async def _mock_planning(*args, **kwargs):
+ yield AIHelperTokensUsed(prompt_tokens=5, completion_tokens=10)
+ yield AIHelperTokensUsed(prompt_tokens=3, completion_tokens=7)
+
+ agent._planning.run = _mock_planning
+
+ result, ok = await agent.run_ephemeral("task", profile_id="test")
+ assert ok is True
+
+ # Drain sink for SubagentComplete
+ subagent_complete = None
+ while not sink.empty():
+ item = await sink.get()
+ if isinstance(item, SubagentComplete):
+ subagent_complete = item
+
+ # Planning tokens: (5+10) + (3+7) = 25
+ # Final LLM call: 0 (no tokens in FakeLLMBackend default)
+ assert subagent_complete is not None
+ assert subagent_complete.token_count == 25
+ finally:
+ current_event_sink.reset(token)
+ agent._planning.run = original_planning_run
+
+ @pytest.mark.asyncio
+ async def test_run_ephemeral_thinking_stall(self, agent):
+ """Subagent that produces only thinking for too long is aborted."""
+ async def _thinking_only(self, **kwargs):
+ for _ in range(200):
+ yield LLMChunk(thinking="thinking " * 100)
+ yield LLMChunk(delta="done", finish_reason="stop")
+
+ backend = FakeLLMBackend()
+ backend.stream_complete = _thinking_only
+ agent._backends.register("ollama", backend)
+
+ result, ok = await agent.run_ephemeral("task", profile_id="test")
+ assert ok is False
+ assert "thinking" in result.lower() or "stall" in result.lower()
diff --git a/tests/unit/core/test_agent_context_size.py b/tests/unit/core/test_agent_context_size.py
index 383a7bd..84082f6 100644
--- a/tests/unit/core/test_agent_context_size.py
+++ b/tests/unit/core/test_agent_context_size.py
@@ -36,8 +36,8 @@
def test_exceeds_window_raises(self):
agent = Agent(None, None, None, None)
- # 128 ctx - 8 reserve = 120 available; each char ~0.25 tokens
- # Need > 120 * 4 = 480 chars to exceed
+ # 128 ctx - 8 reserve = 120 available; each char ~0.33 tokens
+ # Need > 120 * 3 = 360 chars to exceed
msgs = [Message(role="user", content="x" * 600)]
with pytest.raises(ContextTooLargeError) as exc_info:
agent._check_context_size(msgs)
diff --git a/tests/unit/core/test_compressor.py b/tests/unit/core/test_compressor.py
index af0ae6f..262d366 100644
--- a/tests/unit/core/test_compressor.py
+++ b/tests/unit/core/test_compressor.py
@@ -3,6 +3,7 @@
import pytest
from navi.core.compressor import (
+ ContextCompressor,
_format_for_summary,
compress_context,
partition_messages,
@@ -209,3 +210,168 @@
assert new_context[1].role == "user"
assert new_context[1].content == "build a model"
assert len(new_context) == 6 # summary + user + 4 recent messages
+
+ async def test_intra_turn_fallback_aggressive(self):
+ """When turn-based partition has nothing to compress but keep_recent_messages
+ is set, an aggressive fallback (keep_recent_messages=2) should still find
+ something to summarize.
+
+ Here the current turn is exactly 5 messages (user + 2 assistant/tool pairs).
+ With keep_recent_messages=4, partition_current_turn_messages returns None
+ because len(turn) <= keep_recent_messages + 1. This forces the fallback to
+ retry with keep_recent_messages=2, which successfully compresses."""
+ backend = FakeLLMBackend(responses=["aggressive summary"])
+ context = [Message(role="user", content="autonomous loop")]
+ for i in range(2):
+ context.append(Message(
+ role="assistant",
+ tool_calls=[ToolCallRequest(id=str(i), name="fs", arguments={})],
+ ))
+ context.append(Message(role="tool", content=f"result {i}", name="fs", tool_call_id=str(i)))
+
+ # Single turn, keep_recent=1 → turn-based partition returns ([], non_system)
+ # Fallback should kick in with keep_recent_messages=2
+ new_context, summary = await compress_context(
+ context=context,
+ llm=backend,
+ model="test",
+ temperature=0.3,
+ keep_recent=1,
+ keep_recent_messages=4,
+ )
+
+ assert summary == "aggressive summary"
+ assert new_context[0].is_summary is True
+ assert new_context[1].role == "user"
+ # Fallback with keep_recent_messages=2 keeps user + 2 newest messages
+ assert len(new_context) == 4 # summary + user + 2 recent messages
+
+
+class TestContextCompressor:
+ def test_estimate_context_tokens_text_only(self):
+ compressor = ContextCompressor()
+ context = [Message(role="user", content="hello world")]
+ assert compressor.estimate_context_tokens(context) == 3 # 11 chars // 3 = 3
+
+ def test_estimate_context_tokens_with_images(self):
+ compressor = ContextCompressor()
+ context = [Message(role="user", content="hi", images=["base64img"])]
+ assert compressor.estimate_context_tokens(context) == 500 # 2 chars // 3 = 0 + 500
+
+ @pytest.mark.asyncio
+ async def test_compress_session_success(self):
+ backend = FakeLLMBackend(responses=["Summary text"])
+ compressor = ContextCompressor()
+ context = [
+ Message(role="system", content="sys"),
+ Message(role="user", content="1"),
+ Message(role="assistant", content="a1"),
+ Message(role="user", content="2"),
+ Message(role="assistant", content="a2"),
+ Message(role="user", content="3"),
+ Message(role="assistant", content="a3"),
+ ]
+ result = await compressor.compress_session(
+ context=context,
+ llm=backend,
+ model="test",
+ temperature=0.3,
+ keep_recent=2,
+ )
+ assert result is not None
+ new_context, summary = result
+ assert summary == "Summary text"
+ assert len(new_context) == 6 # system + summary + 2 recent turns
+
+ @pytest.mark.asyncio
+ async def test_compress_session_retry_on_failure(self):
+ """First attempt fails, second succeeds with keep_recent + 4."""
+ import navi.core.compressor as compressor_module
+ from unittest.mock import AsyncMock
+
+ backend = FakeLLMBackend(responses=["Summary text"])
+ original_compress_context = compressor_module.compress_context
+ call_count = 0
+
+ async def _failing_once(*args, **kwargs):
+ nonlocal call_count
+ call_count += 1
+ if call_count == 1:
+ raise RuntimeError("boom")
+ return await original_compress_context(*args, **kwargs)
+
+ compressor_module.compress_context = _failing_once
+ try:
+ compressor = ContextCompressor()
+ context = [Message(role="system", content="sys")]
+ for i in range(7):
+ context.append(Message(role="user", content=str(i)))
+ context.append(Message(role="assistant", content=f"a{i}"))
+ result = await compressor.compress_session(
+ context=context,
+ llm=backend,
+ model="test",
+ temperature=0.3,
+ keep_recent=2,
+ )
+ assert result is not None
+ assert call_count == 2
+ finally:
+ compressor_module.compress_context = original_compress_context
+
+ @pytest.mark.asyncio
+ async def test_compress_session_hard_truncate_on_double_failure(self):
+ """Both attempts fail → hard-truncate fallback."""
+ import navi.core.compressor as compressor_module
+ from unittest.mock import AsyncMock
+
+ original_compress_context = compressor_module.compress_context
+
+ async def _always_fail(*args, **kwargs):
+ raise RuntimeError("always fails")
+
+ compressor_module.compress_context = _always_fail
+ try:
+ compressor = ContextCompressor()
+ context = [
+ Message(role="system", content="sys"),
+ Message(role="user", content="1"),
+ Message(role="assistant", content="a1"),
+ Message(role="user", content="2"),
+ Message(role="assistant", content="a2"),
+ Message(role="user", content="3"),
+ Message(role="assistant", content="a3"),
+ Message(role="user", content="4"),
+ Message(role="assistant", content="a4"),
+ ]
+ result = await compressor.compress_session(
+ context=context,
+ llm=AsyncMock(),
+ model="test",
+ temperature=0.3,
+ keep_recent=2,
+ )
+ assert result is not None
+ new_context, summary = result
+ assert "truncated" in summary.lower()
+ # system + 6 kept = 7
+ assert len(new_context) == 7
+ finally:
+ compressor_module.compress_context = original_compress_context
+
+ @pytest.mark.asyncio
+ async def test_compress_session_returns_none_when_nothing_to_compress(self):
+ backend = FakeLLMBackend()
+ compressor = ContextCompressor()
+ context = [
+ Message(role="user", content="hi"),
+ Message(role="assistant", content="hello"),
+ ]
+ result = await compressor.compress_session(
+ context=context,
+ llm=backend,
+ model="test",
+ temperature=0.3,
+ keep_recent=5,
+ )
+ assert result is None
diff --git a/tests/unit/core/test_events.py b/tests/unit/core/test_events.py
index 67f75e7..b3b1222 100644
--- a/tests/unit/core/test_events.py
+++ b/tests/unit/core/test_events.py
@@ -4,6 +4,7 @@
from navi.core.events import (
AIHelperTokensUsed,
+ CompressionStarted,
ContextCompressed,
PlanReady,
PlanningDebugData,
@@ -143,6 +144,15 @@
assert wire["is_subagent"] is True
+class TestCompressionStarted:
+ def test_to_wire(self):
+ ev = CompressionStarted(context_tokens=5000, max_context_tokens=8192)
+ wire = ev.to_wire()
+ assert wire["type"] == "compression_started"
+ assert wire["context_tokens"] == 5000
+ assert wire["max_context_tokens"] == 8192
+
+
class TestInternalEvents:
"""Internal events must NOT serialize to the wire."""
diff --git a/tests/unit/store/test_kv_store.py b/tests/unit/store/test_kv_store.py
new file mode 100644
index 0000000..5de2bb3
--- /dev/null
+++ b/tests/unit/store/test_kv_store.py
@@ -0,0 +1,105 @@
+"""Unit tests for navi.store.KvStore."""
+
+import pytest
+
+from navi.store import KvStore
+from tests.conftest_factory import FakeConnection, FakePool, FakeRecord
+
+
+class TestKvStore:
+ @pytest.fixture
+ def store(self):
+ s = KvStore(dsn="postgresql://fake")
+ s._pool = FakePool()
+ return s
+
+ @pytest.mark.asyncio
+ async def test_get_missing(self, store):
+ store._pool._conn.enqueue(None)
+ result = await store.get(None, "sess1", "todo", "task1")
+ assert result is None
+
+ @pytest.mark.asyncio
+ async def test_set_and_get(self, store):
+ store._pool._conn.enqueue("OK")
+ await store.set(None, "sess1", "todo", "task1", "value1")
+
+ store._pool._conn.enqueue(FakeRecord(value="value1"))
+ result = await store.get(None, "sess1", "todo", "task1")
+ assert result == "value1"
+
+ @pytest.mark.asyncio
+ async def test_set_overwrites(self, store):
+ store._pool._conn.enqueue("OK")
+ await store.set(None, "sess1", "todo", "key", "first")
+
+ store._pool._conn.enqueue("OK")
+ await store.set(None, "sess1", "todo", "key", "second")
+
+ store._pool._conn.enqueue(FakeRecord(value="second"))
+ result = await store.get(None, "sess1", "todo", "key")
+ assert result == "second"
+
+ @pytest.mark.asyncio
+ async def test_get_all(self, store):
+ store._pool._conn.enqueue([
+ FakeRecord(key="a", value="1"),
+ FakeRecord(key="b", value="2"),
+ ])
+ result = await store.get_all(None, "sess1", "todo")
+ assert result == {"a": "1", "b": "2"}
+
+ @pytest.mark.asyncio
+ async def test_delete(self, store):
+ store._pool._conn.enqueue("OK")
+ await store.set(None, "sess1", "todo", "key", "val")
+
+ store._pool._conn.enqueue("OK")
+ await store.delete(None, "sess1", "todo", "key")
+
+ store._pool._conn.enqueue(None)
+ result = await store.get(None, "sess1", "todo", "key")
+ assert result is None
+
+ @pytest.mark.asyncio
+ async def test_clear_scope(self, store):
+ store._pool._conn.enqueue("OK")
+ await store.set(None, "sess1", "todo", "key1", "val1")
+ store._pool._conn.enqueue("OK")
+ await store.set(None, "sess1", "todo", "key2", "val2")
+
+ store._pool._conn.enqueue("OK")
+ await store.clear_scope(None, "sess1", "todo")
+
+ store._pool._conn.enqueue([])
+ result = await store.get_all(None, "sess1", "todo")
+ assert result == {}
+
+ @pytest.mark.asyncio
+ async def test_null_user_id_normalized(self, store):
+ """None user_id is normalized to '' before queries — prevents duplicate
+ rows because PostgreSQL treats NULL as distinct in unique constraints."""
+ store._pool._conn.enqueue("OK")
+ await store.set(None, "sess1", "todo", "key", "val")
+
+ # Verify the query used '' not NULL
+ calls = store._pool._conn.calls
+ execute_call = [c for c in calls if c[0] == "execute"][0]
+ assert execute_call[2][0] == "" # first arg is user_id = ''
+
+ @pytest.mark.asyncio
+ async def test_different_sessions_isolated(self, store):
+ store._pool._conn.enqueue("OK")
+ await store.set(None, "sess1", "todo", "key", "val1")
+
+ store._pool._conn.enqueue("OK")
+ await store.set(None, "sess2", "todo", "key", "val2")
+
+ store._pool._conn.enqueue(FakeRecord(value="val1"))
+ result1 = await store.get(None, "sess1", "todo", "key")
+
+ store._pool._conn.enqueue(FakeRecord(value="val2"))
+ result2 = await store.get(None, "sess2", "todo", "key")
+
+ assert result1 == "val1"
+ assert result2 == "val2"
diff --git a/tests/unit/tools/test_image_view.py b/tests/unit/tools/test_image_view.py
new file mode 100644
index 0000000..32f49f8
--- /dev/null
+++ b/tests/unit/tools/test_image_view.py
@@ -0,0 +1,114 @@
+"""Unit tests for navi.tools.image_view."""
+
+import io
+from pathlib import Path
+from unittest.mock import AsyncMock, patch
+
+import pytest
+from PIL import Image
+
+from navi.tools.image_view import ImageViewTool
+
+
+def _make_image_bytes(mode="RGB", size=(100, 80), fmt="PNG") -> bytes:
+ img = Image.new(mode, size, color=(255, 0, 0))
+ buf = io.BytesIO()
+ img.save(buf, format=fmt)
+ return buf.getvalue()
+
+
+# ── _preprocess tests ────────────────────────────────────────────────────────
+
+
+class TestPreprocess:
+ def test_keeps_small_image(self):
+ raw = _make_image_bytes(size=(100, 80))
+ processed, mime = ImageViewTool._preprocess(raw)
+ assert mime == "image/jpeg"
+ img = Image.open(io.BytesIO(processed))
+ assert img.size == (100, 80)
+
+ def test_resizes_large_image(self):
+ raw = _make_image_bytes(size=(2000, 1500))
+ processed, mime = ImageViewTool._preprocess(raw)
+ assert mime == "image/jpeg"
+ img = Image.open(io.BytesIO(processed))
+ assert max(img.size) == 1024
+
+ def test_converts_rgba_to_rgb(self):
+ raw = _make_image_bytes(mode="RGBA", size=(50, 50))
+ processed, mime = ImageViewTool._preprocess(raw)
+ img = Image.open(io.BytesIO(processed))
+ assert img.mode == "RGB"
+
+
+# ── execute tests ────────────────────────────────────────────────────────────
+
+
+class TestExecute:
+ @pytest.mark.asyncio
+ async def test_read_file_success(self, tmp_path: Path):
+ img_path = tmp_path / "test.png"
+ img_path.write_bytes(_make_image_bytes(size=(100, 80)))
+
+ tool = ImageViewTool()
+ result = await tool.execute({"source": str(img_path)})
+ assert result.success is True
+ assert "Image loaded" in result.output
+ assert result.metadata["mime"] == "image/jpeg"
+ assert "base64" in result.metadata
+
+ @pytest.mark.asyncio
+ async def test_mime_guard_rejects_non_image(self, tmp_path: Path):
+ txt_path = tmp_path / "test.txt"
+ txt_path.write_text("not an image")
+
+ tool = ImageViewTool()
+ result = await tool.execute({"source": str(txt_path)})
+ assert result.success is False
+ assert "Unsupported" in str(result.error)
+
+ @pytest.mark.asyncio
+ async def test_fetch_url_success(self):
+ tool = ImageViewTool()
+ raw = _make_image_bytes(size=(100, 80))
+
+ from unittest.mock import MagicMock
+
+ mock_response = MagicMock()
+ mock_response.headers = {"content-type": "image/png"}
+ mock_response.content = raw
+ mock_response.raise_for_status = MagicMock()
+
+ mock_client = AsyncMock()
+ mock_client.__aenter__ = AsyncMock(return_value=mock_client)
+ mock_client.__aexit__ = AsyncMock(return_value=False)
+ mock_client.get = AsyncMock(return_value=mock_response)
+
+ with patch("navi.tools.image_view.httpx.AsyncClient", return_value=mock_client):
+ result = await tool.execute({"source": "https://example.com/img.png"})
+
+ assert result.success is True
+ assert "Image loaded" in result.output
+ assert result.metadata["mime"] == "image/jpeg"
+
+ @pytest.mark.asyncio
+ async def test_fetch_url_rejects_svg(self):
+ from unittest.mock import MagicMock
+
+ tool = ImageViewTool()
+ mock_response = MagicMock()
+ mock_response.headers = {"content-type": "image/svg+xml"}
+ mock_response.content = b""
+ mock_response.raise_for_status = MagicMock()
+
+ mock_client = AsyncMock()
+ mock_client.__aenter__ = AsyncMock(return_value=mock_client)
+ mock_client.__aexit__ = AsyncMock(return_value=False)
+ mock_client.get = AsyncMock(return_value=mock_response)
+
+ with patch("navi.tools.image_view.httpx.AsyncClient", return_value=mock_client):
+ result = await tool.execute({"source": "https://example.com/img.svg"})
+
+ assert result.success is False
+ assert "SVG" in str(result.error)
diff --git a/tests/unit/tools/test_memory.py b/tests/unit/tools/test_memory.py
new file mode 100644
index 0000000..775ba6f
--- /dev/null
+++ b/tests/unit/tools/test_memory.py
@@ -0,0 +1,140 @@
+"""Unit tests for navi.tools.memory."""
+
+from unittest.mock import AsyncMock
+
+import pytest
+
+from navi.tools.memory import MemoryTool
+from navi.tools._internal.base import current_session_id, current_user_id
+
+
+@pytest.fixture
+def fake_store():
+ store = AsyncMock()
+ store.upsert_fact = AsyncMock()
+ store.search_facts = AsyncMock(return_value=[])
+ store.delete_fact = AsyncMock(return_value=1)
+ store.get_categories = AsyncMock(return_value=[])
+ return store
+
+
+@pytest.fixture(autouse=True)
+def _fake_ctx():
+ token = current_session_id.set("sess1")
+ token2 = current_user_id.set("user1")
+ yield
+ current_session_id.reset(token)
+ current_user_id.reset(token2)
+
+
+@pytest.mark.asyncio
+async def test_save(fake_store):
+ tool = MemoryTool(fake_store)
+ result = await tool.execute({
+ "action": "save",
+ "category": "technical",
+ "key": "primary_os",
+ "value": "Arch Linux",
+ "source": "tool_call",
+ "confidence": 95,
+ })
+ assert result.success is True
+ assert "Saved [technical] primary_os" in result.output
+ fake_store.upsert_fact.assert_awaited_once()
+
+
+@pytest.mark.asyncio
+async def test_save_missing_category(fake_store):
+ tool = MemoryTool(fake_store)
+ result = await tool.execute({
+ "action": "save",
+ "key": "primary_os",
+ "value": "Arch Linux",
+ })
+ assert result.success is False
+ assert "category" in result.output.lower()
+
+
+@pytest.mark.asyncio
+async def test_save_invalid_category(fake_store):
+ tool = MemoryTool(fake_store)
+ result = await tool.execute({
+ "action": "save",
+ "category": "invalid",
+ "key": "primary_os",
+ "value": "Arch Linux",
+ })
+ assert result.success is False
+ assert "Invalid category" in result.output
+
+
+@pytest.mark.asyncio
+async def test_search_no_results(fake_store):
+ tool = MemoryTool(fake_store)
+ result = await tool.execute({
+ "action": "search",
+ "query": "nonexistent",
+ })
+ assert result.success is True
+ assert "No matching facts" in result.output
+
+
+@pytest.mark.asyncio
+async def test_search_with_results(fake_store):
+ fake_store.search_facts = AsyncMock(return_value=[{
+ "category": "technical",
+ "key": "primary_os",
+ "value": "Arch Linux",
+ "source": "tool_call",
+ "confidence": 95,
+ "source_context": "found via uname",
+ }])
+ tool = MemoryTool(fake_store)
+ result = await tool.execute({
+ "action": "search",
+ "query": "os",
+ })
+ assert result.success is True
+ assert "Arch Linux" in result.output
+ assert "technical" in result.output
+
+
+@pytest.mark.asyncio
+async def test_forget(fake_store):
+ tool = MemoryTool(fake_store)
+ result = await tool.execute({
+ "action": "forget",
+ "key": "primary_os",
+ })
+ assert result.success is True
+ assert "Deleted 1 fact" in result.output
+
+
+@pytest.mark.asyncio
+async def test_forget_not_found(fake_store):
+ fake_store.delete_fact = AsyncMock(return_value=0)
+ tool = MemoryTool(fake_store)
+ result = await tool.execute({
+ "action": "forget",
+ "key": "missing",
+ })
+ assert result.success is False
+ assert "No fact found" in result.output
+
+
+@pytest.mark.asyncio
+async def test_list_categories(fake_store):
+ fake_store.get_categories = AsyncMock(return_value=["technical", "preferences"])
+ tool = MemoryTool(fake_store)
+ result = await tool.execute({"action": "list"})
+ assert result.success is True
+ assert "technical" in result.output
+ assert "preferences" in result.output
+
+
+@pytest.mark.asyncio
+async def test_list_empty(fake_store):
+ tool = MemoryTool(fake_store)
+ result = await tool.execute({"action": "list"})
+ assert result.success is True
+ assert "empty" in result.output.lower()
diff --git a/tests/unit/tools/test_scratchpad.py b/tests/unit/tools/test_scratchpad.py
new file mode 100644
index 0000000..efbc560
--- /dev/null
+++ b/tests/unit/tools/test_scratchpad.py
@@ -0,0 +1,118 @@
+"""Unit tests for navi.tools.scratchpad."""
+
+import pytest
+
+from navi.tools.scratchpad import ScratchpadTool, get_section, _kv_store
+from navi.tools._internal.base import current_session_id, current_user_id
+from navi.store import KvStore
+from tests.conftest_factory import FakePool
+
+
+class FakeKvStore(KvStore):
+ def __init__(self):
+ self._data: dict[tuple, str] = {}
+
+ async def _get_pool(self):
+ return FakePool()
+
+ async def get(self, user_id, session_id, scope, key):
+ return self._data.get((user_id or "", session_id, scope, key))
+
+ async def set(self, user_id, session_id, scope, key, value):
+ self._data[(user_id or "", session_id, scope, key)] = value
+
+ async def get_all(self, user_id, session_id, scope):
+ return {
+ k[3]: v
+ for k, v in self._data.items()
+ if k[:3] == (user_id or "", session_id, scope)
+ }
+
+ async def delete(self, user_id, session_id, scope, key):
+ self._data.pop((user_id or "", session_id, scope, key), None)
+
+ async def clear_scope(self, user_id, session_id, scope):
+ keys = [k for k in self._data if k[:3] == (user_id or "", session_id, scope)]
+ for k in keys:
+ del self._data[k]
+
+
+@pytest.fixture(autouse=True)
+def _fake_kv():
+ store = FakeKvStore()
+ from navi.tools import scratchpad as _mod
+ _mod._kv_store = store
+ yield store
+ _mod._kv_store = None
+
+
+@pytest.fixture(autouse=True)
+def _fake_ctx():
+ token = current_session_id.set("sess1")
+ token2 = current_user_id.set("user1")
+ yield
+ current_session_id.reset(token)
+ current_user_id.reset(token2)
+
+
+@pytest.mark.asyncio
+async def test_write_then_read(_fake_kv):
+ tool = ScratchpadTool()
+ result = await tool.execute({"op": "write", "section": "findings", "content": "found X"})
+ assert result.success is True
+
+ result = await tool.execute({"op": "read", "section": "findings"})
+ assert result.success is True
+ assert "found X" in result.output
+
+
+@pytest.mark.asyncio
+async def test_append(_fake_kv):
+ tool = ScratchpadTool()
+ await tool.execute({"op": "write", "section": "findings", "content": "line1"})
+ result = await tool.execute({"op": "append", "section": "findings", "content": "line2"})
+ assert result.success is True
+
+ result = await tool.execute({"op": "read", "section": "findings"})
+ assert "line1" in result.output
+ assert "line2" in result.output
+
+
+@pytest.mark.asyncio
+async def test_read_all_sections(_fake_kv):
+ tool = ScratchpadTool()
+ await tool.execute({"op": "write", "section": "goal", "content": "do thing"})
+ await tool.execute({"op": "write", "section": "findings", "content": "found"})
+ result = await tool.execute({"op": "read"})
+ assert result.success is True
+ assert "goal" in result.output
+ assert "findings" in result.output
+
+
+@pytest.mark.asyncio
+async def test_clear_section(_fake_kv):
+ tool = ScratchpadTool()
+ await tool.execute({"op": "write", "section": "goal", "content": "do thing"})
+ result = await tool.execute({"op": "clear", "section": "goal"})
+ assert result.success is True
+
+ result = await tool.execute({"op": "read", "section": "goal"})
+ assert "empty" in result.output.lower()
+
+
+@pytest.mark.asyncio
+async def test_scope_isolation(_fake_kv):
+ tool = ScratchpadTool()
+ await tool.execute({"op": "write", "section": "main", "content": "sess1 data"})
+
+ current_session_id.set("sess2")
+ result = await tool.execute({"op": "read", "section": "main"})
+ assert "empty" in result.output.lower()
+
+
+@pytest.mark.asyncio
+async def test_get_section(_fake_kv):
+ tool = ScratchpadTool()
+ await tool.execute({"op": "write", "section": "artifacts", "content": "path/to/file"})
+ text = await get_section("sess1", "artifacts")
+ assert text == "path/to/file"
diff --git a/tests/unit/tools/test_todo.py b/tests/unit/tools/test_todo.py
new file mode 100644
index 0000000..79de193
--- /dev/null
+++ b/tests/unit/tools/test_todo.py
@@ -0,0 +1,142 @@
+"""Unit tests for navi.tools.todo."""
+
+import json
+
+import pytest
+
+from navi.llm.base import Message
+from navi.tools.todo import (
+ TodoTool,
+ get_failed_steps,
+ get_progress_message,
+ get_task_snapshot,
+ set_tasks,
+ _kv_store,
+)
+from navi.tools._internal.base import current_session_id, current_user_id
+from navi.store import KvStore
+from tests.conftest_factory import FakeConnection, FakePool
+
+
+class FakeKvStore(KvStore):
+ """In-memory KV store for tests."""
+
+ def __init__(self):
+ self._data: dict[tuple, str] = {}
+
+ async def _get_pool(self):
+ return FakePool()
+
+ async def get(self, user_id, session_id, scope, key):
+ return self._data.get((user_id or "", session_id, scope, key))
+
+ async def set(self, user_id, session_id, scope, key, value):
+ self._data[(user_id or "", session_id, scope, key)] = value
+
+ async def get_all(self, user_id, session_id, scope):
+ return {
+ k[3]: v
+ for k, v in self._data.items()
+ if k[:3] == (user_id or "", session_id, scope)
+ }
+
+ async def delete(self, user_id, session_id, scope, key):
+ self._data.pop((user_id or "", session_id, scope, key), None)
+
+ async def clear_scope(self, user_id, session_id, scope):
+ keys = [k for k in self._data if k[:3] == (user_id or "", session_id, scope)]
+ for k in keys:
+ del self._data[k]
+
+
+@pytest.fixture(autouse=True)
+def _fake_kv():
+ store = FakeKvStore()
+ from navi.tools import todo as _mod
+ _mod._kv_store = store
+ yield store
+ _mod._kv_store = None
+
+
+@pytest.fixture(autouse=True)
+def _fake_ctx():
+ token = current_session_id.set("sess1")
+ token2 = current_user_id.set("user1")
+ yield
+ current_session_id.reset(token)
+ current_user_id.reset(token2)
+
+
+# ── TodoTool execute tests ────────────────────────────────────────────────────
+
+
+@pytest.mark.asyncio
+async def test_set_tasks(_fake_kv):
+ tool = TodoTool()
+ result = await tool.execute({"op": "set", "tasks": ["task A", "task B"]})
+ assert result.success is True
+ assert "task A" in result.output
+ assert "task B" in result.output
+
+
+@pytest.mark.asyncio
+async def test_view_empty(_fake_kv):
+ tool = TodoTool()
+ result = await tool.execute({"op": "view"})
+ assert result.success is True
+ assert "No plan set" in result.output
+
+
+@pytest.mark.asyncio
+async def test_update_status(_fake_kv):
+ tool = TodoTool()
+ await tool.execute({"op": "set", "tasks": ["task A"]})
+ result = await tool.execute({"op": "update", "index": 1, "status": "done", "validation": "tested"})
+ assert result.success is True
+ assert "done" in result.output
+
+
+@pytest.mark.asyncio
+async def test_done_requires_validation(_fake_kv):
+ tool = TodoTool()
+ await tool.execute({"op": "set", "tasks": ["task A"]})
+ result = await tool.execute({"op": "update", "index": 1, "status": "done"})
+ assert result.success is False
+ assert "validation" in result.error.lower()
+
+
+@pytest.mark.asyncio
+async def test_failed_without_validation_warns(_fake_kv):
+ tool = TodoTool()
+ await tool.execute({"op": "set", "tasks": ["task A"]})
+ result = await tool.execute({"op": "update", "index": 1, "status": "failed"})
+ assert result.success is True
+ assert "Tip" in result.output
+
+
+@pytest.mark.asyncio
+async def test_clear(_fake_kv):
+ tool = TodoTool()
+ await tool.execute({"op": "set", "tasks": ["task A"]})
+ result = await tool.execute({"op": "clear"})
+ assert result.success is True
+ assert "cleared" in result.output.lower()
+
+
+# ── Public API tests ─────────────────────────────────────────────────────────
+
+
+@pytest.mark.asyncio
+async def test_get_task_snapshot(_fake_kv):
+ await set_tasks("sess1", ["t1", "t2"])
+ snapshot = await get_task_snapshot("sess1")
+ assert snapshot == frozenset({("t1", "pending"), ("t2", "pending")})
+
+
+@pytest.mark.asyncio
+async def test_get_progress_message(_fake_kv):
+ await set_tasks("sess1", ["t1", "t2"])
+ msg = await get_progress_message("sess1", first_iteration=True)
+ assert isinstance(msg, Message)
+ assert msg.role == "system"
+ assert "TODO progress" in msg.content
diff --git a/webclient/dist/assets/index-BokRfynu.css b/webclient/dist/assets/index-BokRfynu.css
deleted file mode 100644
index af3bd5e..0000000
--- a/webclient/dist/assets/index-BokRfynu.css
+++ /dev/null
@@ -1 +0,0 @@
-@charset "UTF-8";.vue-recycle-scroller__resize-observer[data-v-08cc04ab]{position:absolute;top:0;right:0;bottom:0;left:0;opacity:0;pointer-events:none;z-index:-1}.vue-recycle-scroller{position:relative}.vue-recycle-scroller.direction-vertical:not(.page-mode){overflow-y:auto}.vue-recycle-scroller.direction-horizontal:not(.page-mode){overflow-x:auto}.vue-recycle-scroller.grid-mode:not(.page-mode){overflow:auto}.vue-recycle-scroller.direction-horizontal{display:flex}.vue-recycle-scroller__slot{flex:auto 0 0}.vue-recycle-scroller__item-wrapper{flex:1;box-sizing:border-box;overflow:hidden;position:relative}.vue-recycle-scroller.ready .vue-recycle-scroller__item-view{position:absolute;top:0;left:0;will-change:transform}.vue-recycle-scroller.direction-vertical .vue-recycle-scroller__item-wrapper{width:100%}.vue-recycle-scroller.direction-horizontal .vue-recycle-scroller__item-wrapper{height:100%}.vue-recycle-scroller.ready.direction-vertical .vue-recycle-scroller__item-view{width:100%}.vue-recycle-scroller.ready.direction-horizontal .vue-recycle-scroller__item-view{height:100%}.container[data-v-73f7dfc6]{padding:18px}.section[data-v-73f7dfc6]{margin-bottom:48px}.section-title[data-v-73f7dfc6],.block[data-v-73f7dfc6]{margin-bottom:34px}.block-title[data-v-73f7dfc6]{margin-bottom:22px}p[data-v-73f7dfc6],.text[data-v-73f7dfc6]{margin-bottom:15px}.hint[data-v-73f7dfc6]{margin-top:8px}.list[data-v-73f7dfc6]{padding-left:22px;margin-bottom:15px}.list-item[data-v-73f7dfc6]{margin-bottom:8px}.list-nested[data-v-73f7dfc6]{margin-top:8px}.table[data-v-73f7dfc6]{margin-bottom:22px}.table-caption[data-v-73f7dfc6]{margin-bottom:8px}.form-group[data-v-73f7dfc6]{margin-bottom:15px}.label[data-v-73f7dfc6]{margin-bottom:5px;display:block}.input[data-v-73f7dfc6],.textarea[data-v-73f7dfc6],.select[data-v-73f7dfc6]{margin-top:5px}.toast[data-v-73f7dfc6]{padding:15px}.toast-stack[data-v-73f7dfc6]{gap:8px}.search-highlight[data-v-73f7dfc6]{background:#7aa2f740;color:#7aa2f7;font-weight:600;padding:0 2px;border-radius:2px}.session-name-row[data-v-73f7dfc6]{display:flex;align-items:center;gap:6px;font-weight:500;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.recall-badge[data-v-73f7dfc6]{color:var(--color-accent, #f59e0b);font-size:.85em;flex-shrink:0}.session-list-wrap[data-v-5a757df4]{flex:1;overflow:hidden;display:flex;flex-direction:column}.session-scroller[data-v-5a757df4]{flex:1;overflow-y:auto}.empty-sessions[data-v-5a757df4]{display:flex;flex-direction:column;align-items:center;gap:8px;padding:32px 16px;color:var(--color-text-dark, #787c99);font-size:13px}.empty-sessions i[data-v-5a757df4]{font-size:32px;opacity:.4}.empty-sessions p[data-v-5a757df4]{margin:0}.sessions-loading[data-v-5a757df4]{display:flex;align-items:center;justify-content:center;gap:10px;padding:28px 16px;color:var(--color-text-dark, #787c99);font-size:12px}.sessions-loading-more[data-v-5a757df4]{padding:10px 16px 14px}.sessions-spinner[data-v-5a757df4]{width:16px;height:16px;border:2px solid var(--color-border, #3b4261);border-top-color:var(--color-accent, #7aa2f7);border-radius:50%;animation:sessions-spin-5a757df4 .8s linear infinite}@keyframes sessions-spin-5a757df4{to{transform:rotate(360deg)}}.ptr-indicator[data-v-5a757df4]{position:absolute;top:0;left:0;right:0;z-index:10;display:flex;align-items:center;justify-content:center;gap:8px;padding:8px;font-size:12px;color:var(--color-text-dark, #787c99);pointer-events:none;transition:opacity .15s,transform .15s;will-change:transform,opacity}.ptr-spinner[data-v-5a757df4]{width:16px;height:16px;border:2px solid var(--color-border, #3b4261);border-top-color:var(--color-accent, #7aa2f7);border-radius:50%;transition:transform .15s}.ptr-spinning[data-v-5a757df4]{animation:sessions-spin-5a757df4 .8s linear infinite}.ptr-pulled[data-v-5a757df4]{transition:transform .15s}@media(min-width:769px){.ptr-indicator[data-v-5a757df4]{display:none}}.container[data-v-780609b7]{padding:18px}.section[data-v-780609b7]{margin-bottom:48px}.section-title[data-v-780609b7],.block[data-v-780609b7]{margin-bottom:34px}.block-title[data-v-780609b7]{margin-bottom:22px}p[data-v-780609b7],.text[data-v-780609b7]{margin-bottom:15px}.hint[data-v-780609b7]{margin-top:8px}.list[data-v-780609b7]{padding-left:22px;margin-bottom:15px}.list-item[data-v-780609b7]{margin-bottom:8px}.list-nested[data-v-780609b7]{margin-top:8px}.table[data-v-780609b7]{margin-bottom:22px}.table-caption[data-v-780609b7]{margin-bottom:8px}.form-group[data-v-780609b7]{margin-bottom:15px}.label[data-v-780609b7]{margin-bottom:5px;display:block}.input[data-v-780609b7],.textarea[data-v-780609b7],.select[data-v-780609b7]{margin-top:5px}.toast[data-v-780609b7]{padding:15px}.toast-stack[data-v-780609b7]{gap:8px}.sidebar-close-btn[data-v-780609b7]{display:none}@media(max-width:1280px){.sidebar-close-btn[data-v-780609b7]{display:flex;margin-left:auto}}.sidebar-search[data-v-780609b7]{display:none;padding:0 15px}.sidebar-search.is-open[data-v-780609b7]{display:block;padding-top:8px;padding-bottom:8px;border-bottom:1px solid var(--color-border)}.sidebar-search-inner[data-v-780609b7]{position:relative;display:flex;align-items:center;gap:5px}.sidebar-search-inner[data-v-780609b7] .search-field{flex:1;min-width:0}.sidebar-search-inner.is-loading[data-v-780609b7] .input-group-addon{position:relative!important}.sidebar-search-inner.is-loading[data-v-780609b7] .input-group-addon>i{display:none!important}.sidebar-search-inner.is-loading[data-v-780609b7] .input-group-addon:after{content:"";display:block;width:12px;height:12px;border:2px solid rgba(192,202,245,.24);border-top-color:#7aa2f7;border-radius:50%;animation:spin .6s linear infinite;margin:auto}.sessions-header-actions[data-v-780609b7]{display:flex;align-items:center;gap:2px}.search-toggle-btn[data-v-780609b7]{font-size:14px;color:#787c99;transition:color .15s}.search-toggle-btn.active[data-v-780609b7],.search-toggle-btn[data-v-780609b7]:hover{color:#c0caf5}.recall-filter-btn[data-v-780609b7]{font-size:14px;color:#787c99;transition:color .15s}.recall-filter-btn.active[data-v-780609b7],.recall-filter-btn[data-v-780609b7]:hover{color:var(--color-accent, #7aa2f7)}.sidebar-footer[data-v-780609b7]{padding:12px 16px;border-top:1px solid var(--color-border);display:flex;align-items:center;justify-content:space-between;gap:8px}.user-info[data-v-780609b7]{display:flex;align-items:center;gap:8px;text-decoration:none;color:inherit;flex:1;min-width:0;cursor:pointer}.user-info:hover .user-name[data-v-780609b7]{color:var(--color-text-primary)}.user-name[data-v-780609b7]{font-size:13px;color:var(--color-text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sidebar-footer-actions[data-v-780609b7]{display:flex;align-items:center;gap:8px}.admin-link[data-v-780609b7]{text-decoration:none}.lightbox-panel{max-width:90vw;min-height:unset;width:fit-content;cursor:default}body .modal .lightbox-panel .modal-body{max-height:90vh;padding:0}.lightbox-img{display:block;width:100%;max-height:90vh;object-fit:cover}.lightbox-error{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:32px;color:#787c99;font-size:13px}.lightbox-error i{font-size:32px}.selection-toolbar[data-v-81606e7c]{position:fixed;transform:translate(-50%);z-index:900;pointer-events:all;background:#e0af68;color:#000}.artifacts-panel[data-v-bdaf6191]{width:var(--artifacts-width, min(600px, 42vw));min-width:var(--artifacts-width, min(600px, 42vw));max-width:var(--artifacts-width, min(600px, 42vw));display:flex;flex-direction:column;background:#16161e;border-left:2px solid rgba(192,202,245,.24);min-height:0;margin-right:calc(-1 * var(--artifacts-width, min(600px, 42vw)));opacity:0;pointer-events:none;transform:translate(100%);position:relative;transition:margin-right .22s ease,opacity .22s ease,transform .22s ease}.artifacts-panel.is-open[data-v-bdaf6191]{margin-right:0;opacity:1;pointer-events:auto;transform:translate(0)}.artifacts-panel.is-resizing[data-v-bdaf6191]{transition:none}.artifacts-resize-handle[data-v-bdaf6191]{position:absolute;top:0;left:-4px;bottom:0;width:8px;z-index:2;cursor:col-resize;touch-action:none}.artifacts-resize-handle[data-v-bdaf6191]:after{content:"";position:absolute;top:0;left:3px;width:1px;height:100%;background:transparent;transition:background .15s ease}.artifacts-resize-handle[data-v-bdaf6191]:hover:after,.artifacts-panel.is-resizing .artifacts-resize-handle[data-v-bdaf6191]:after{background:#ff9e64}.artifacts-header[data-v-bdaf6191]{height:58px;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:0 15px;border-bottom:2px solid rgba(192,202,245,.24)}.artifacts-empty[data-v-bdaf6191]{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;color:#787c99;font-size:13px}.artifacts-empty i[data-v-bdaf6191]{font-size:28px}.artifacts-tabs[data-v-bdaf6191]{display:flex;align-items:center;flex:1}.artifacts-tab[data-v-bdaf6191]{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:46px;padding:12px 15px;border:0;border-right:2px solid rgba(192,202,245,.08);background:transparent;color:#a9b1d6;font-size:13px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;cursor:pointer;transition:background .2s ease,color .2s ease}.artifacts-tab[data-v-bdaf6191]:hover{background:#7aa2f7;color:#16161e}.artifacts-tab.is-active[data-v-bdaf6191]{background:#c0caf5;color:#16161e}.artifacts-tab-count[data-v-bdaf6191]{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;background:#1f2335;color:#787c99;font-size:11px;font-weight:600}.artifacts-tab.is-active .artifacts-tab-count[data-v-bdaf6191]{background:#16161e33;color:#16161e}.artifacts-list[data-v-bdaf6191]{max-height:232px;overflow-y:auto;border-bottom:2px solid rgba(192,202,245,.24)}.artifact-item[data-v-bdaf6191]{width:100%;min-height:50px;display:flex;align-items:center;gap:10px;padding:8px 12px;border:2px solid transparent;background:#c0caf50b;color:#c0caf5;text-align:left;cursor:pointer;transition:background .2s ease,border-color .2s ease,color .2s ease}.artifact-item[data-v-bdaf6191]:hover{background:#7aa2f7;color:#16161e}.artifact-item.is-active[data-v-bdaf6191]{border-color:#7aa2f7;background:#7aa2f7;color:#16161e}.artifact-icon[data-v-bdaf6191]{width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;color:#ff9e64;background:#c0caf516}.artifact-item:hover .artifact-icon[data-v-bdaf6191],.artifact-item.is-active .artifact-icon[data-v-bdaf6191]{color:#16161e;background:#16161e1f}.artifact-info[data-v-bdaf6191]{min-width:0;flex:1;display:flex;flex-direction:column;gap:2px}.artifact-title[data-v-bdaf6191],.artifact-detail-title[data-v-bdaf6191],.artifact-detail-filename[data-v-bdaf6191]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.artifact-title[data-v-bdaf6191]{font-size:13px;font-weight:500}.artifact-meta[data-v-bdaf6191]{font-size:11px;color:#787c99}.artifact-item:hover .artifact-meta[data-v-bdaf6191],.artifact-item.is-active .artifact-meta[data-v-bdaf6191]{color:#16161eb8}.artifact-detail[data-v-bdaf6191]{flex:1;min-height:0;display:flex;flex-direction:column}.artifact-detail-header[data-v-bdaf6191]{padding:12px 15px 8px}.artifact-detail-title[data-v-bdaf6191]{font-size:14px;font-weight:600;color:#c0caf5}.artifact-detail-filename[data-v-bdaf6191]{margin-top:3px;font-size:12px;color:#787c99}.artifact-actions[data-v-bdaf6191]{display:grid;grid-template-columns:repeat(auto-fit,minmax(42px,1fr));gap:6px;padding:0 15px 12px}.artifact-action[data-v-bdaf6191]{height:32px;display:inline-flex;align-items:center;justify-content:center;border:2px solid rgba(192,202,245,.24);background:#1f2335;color:#c0caf5;text-decoration:none;cursor:pointer;transition:background .2s ease,border-color .2s ease,color .2s ease}.artifact-action[data-v-bdaf6191]:hover{background:#7aa2f7;border-color:#7aa2f7;color:#16161e}.artifact-preview[data-v-bdaf6191]{flex:1;min-height:0;border-top:2px solid rgba(192,202,245,.24);background:#0f0f14}.artifact-frame[data-v-bdaf6191],.artifact-image[data-v-bdaf6191],.artifact-video[data-v-bdaf6191]{width:100%;height:100%;border:0;display:block}.artifact-image[data-v-bdaf6191],.artifact-video[data-v-bdaf6191]{object-fit:contain}.artifact-source[data-v-bdaf6191]{height:100%;overflow:auto;background:#0f0f14}.artifact-source-code[data-v-bdaf6191],.artifact-source-error[data-v-bdaf6191]{margin:0;padding:14px;white-space:pre;font-family:IBM Plex Mono,monospace;font-size:12px;line-height:1.6;color:#c0caf5}.artifact-source-error[data-v-bdaf6191]{color:#f7768e}.artifact-source-state[data-v-bdaf6191]{display:flex;align-items:center;gap:8px;padding:14px;color:#787c99;font-size:12px}.artifact-no-preview[data-v-bdaf6191]{height:100%;min-height:220px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;color:#787c99;font-size:13px}.artifact-no-preview i[data-v-bdaf6191]{font-size:28px}.links-list[data-v-bdaf6191]{max-height:none;flex:1;overflow-y:auto}.link-item[data-v-bdaf6191]{text-decoration:none}.link-item .artifact-title[data-v-bdaf6191]{color:#ff9e64}.link-item:hover .artifact-title[data-v-bdaf6191],.link-item.is-active .artifact-title[data-v-bdaf6191]{color:#16161e}.link-detail[data-v-bdaf6191]{padding:12px 15px;border-top:2px solid rgba(192,202,245,.24)}.link-detail-header[data-v-bdaf6191]{margin-bottom:8px}.link-detail-count[data-v-bdaf6191]{font-size:12px;color:#787c99}.link-actions[data-v-bdaf6191]{display:flex;gap:6px}.files-list[data-v-bdaf6191]{max-height:none;flex:1;overflow-y:auto}.file-item[data-v-bdaf6191],.file-item.is-dir[data-v-bdaf6191]{cursor:default}.file-item.is-dir .artifact-title[data-v-bdaf6191]{color:#a9b1d6}.file-row-actions[data-v-bdaf6191]{display:flex;gap:4px;flex-shrink:0;opacity:0;transition:opacity .15s ease}.file-item:hover .file-row-actions[data-v-bdaf6191]{opacity:1}.file-row-action[data-v-bdaf6191]{width:28px;height:28px;min-height:0;padding:0}@media(max-width:980px){.artifacts-panel[data-v-bdaf6191]{position:fixed;top:0;right:0;bottom:0;z-index:120;margin-right:0;transform:translate(100%);width:100vw;min-width:100vw;max-width:100vw}.artifacts-resize-handle[data-v-bdaf6191]{display:none}.artifacts-panel.is-open[data-v-bdaf6191]{transform:translate(0)}.artifacts-header[data-v-bdaf6191]{gap:6px;padding:0 10px}.artifacts-tab[data-v-bdaf6191]{padding:8px 10px;gap:4px}.artifacts-tab>span[data-v-bdaf6191]:not(.artifacts-tab-count){display:none}}@media(prefers-reduced-motion:reduce){.artifacts-panel[data-v-bdaf6191]{transition:none}}.files-tab-wrap[data-v-bdaf6191]{position:relative;flex:1;display:flex;flex-direction:column;overflow:hidden}.files-refresh-btn[data-v-bdaf6191]{position:absolute;top:8px;right:8px;z-index:2;width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;border:2px solid rgba(192,202,245,.24);background:#1f2335;color:#c0caf5;font-size:14px;cursor:pointer;transition:background .2s ease,border-color .2s ease,color .2s ease}.files-refresh-btn[data-v-bdaf6191]:hover{background:#7aa2f7;border-color:#7aa2f7;color:#16161e}.files-refresh-btn[data-v-bdaf6191]:disabled{opacity:.5;cursor:not-allowed}.files-refresh-btn i.spinning[data-v-bdaf6191]{display:inline-block;animation:refresh-spin-bdaf6191 .8s linear infinite}@keyframes refresh-spin-bdaf6191{to{transform:rotate(360deg)}}@media(max-width:980px){.files-refresh-btn[data-v-bdaf6191]{display:none}}.files-ptr[data-v-bdaf6191]{position:absolute;top:0;left:0;right:0;z-index:10;display:flex;align-items:center;justify-content:center;gap:8px;padding:8px;font-size:12px;color:var(--color-text-dark, #787c99);pointer-events:none;transition:opacity .15s,transform .15s;will-change:transform,opacity}.ptr-pulled[data-v-bdaf6191]{transition:transform .15s}@media(min-width:981px){.files-ptr[data-v-bdaf6191]{display:none}}.login-overlay[data-v-6939826e]{position:fixed;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center;background:#111;z-index:9999}.login-card[data-v-6939826e]{display:flex;flex-direction:column;align-items:center;gap:16px;padding:48px 40px;border:1px solid var(--color-border);border-radius:16px;max-width:360px;width:90%}.login-logo[data-v-6939826e]{width:64px;height:64px}.login-title[data-v-6939826e]{font-size:24px;font-weight:700;color:var(--color-text-primary);margin:0}.login-subtitle[data-v-6939826e]{font-size:14px;color:var(--color-text-secondary);margin:0}.login-btn[data-v-6939826e]{margin-top:8px;width:100%;justify-content:center}.welcome-sidebar-btn[data-v-43638b99]{display:none;position:absolute;top:12px;left:12px}@media(max-width:1280px){.welcome-sidebar-btn[data-v-43638b99]{display:flex}}.context-bar-pct[data-v-fe8d0787]{font-size:11px;font-weight:600;font-variant-numeric:tabular-nums;color:var(--color-success);white-space:nowrap}.context-bar-pct.is-warn[data-v-fe8d0787]{color:var(--color-warning)}.context-bar-pct.is-crit[data-v-fe8d0787]{color:var(--color-error)}.btn-artifacts-toggle[data-v-a43d8e5c]{position:relative}.artifact-count[data-v-a43d8e5c]{position:absolute;top:-3px;right:-3px;min-width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center;padding:0 4px;font-size:10px;line-height:1;background:var(--accent, #4ec9b0);color:#11111b}.recall-banner[data-v-a43d8e5c]{display:flex;align-items:center;gap:8px;padding:6px 12px;background:rgba(var(--color-accent-rgb, 122, 162, 247),.12);border-bottom:1px solid var(--color-border, #3b4261);font-size:12px;color:var(--color-text, #a9b1d6)}.recall-banner i[data-v-a43d8e5c]{color:var(--color-accent, #7aa2f7);font-size:14px}.recall-text[data-v-a43d8e5c]{flex:1;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.recall-btn[data-v-a43d8e5c]{background:none;border:none;color:var(--color-text-dark, #787c99);cursor:pointer;padding:2px 4px;font-size:14px;line-height:1;border-radius:4px;transition:color .15s,background .15s}.recall-btn[data-v-a43d8e5c]:hover{color:var(--color-text, #a9b1d6);background:#ffffff0f}.content-card[data-v-929d4ed2]{margin:8px 0;background:var(--surface, #1e1e2e);border:1px solid var(--border, #2a2a3e);overflow:hidden}.content-card summary[data-v-929d4ed2]{display:flex;align-items:center;gap:8px;padding:10px 14px;cursor:pointer;-webkit-user-select:none;user-select:none;list-style:none}.content-card summary[data-v-929d4ed2]::-webkit-details-marker{display:none}.content-icon[data-v-929d4ed2]{font-size:1.2em;line-height:1}.content-title[data-v-929d4ed2]{flex:1;font-size:.9em;font-weight:500;color:var(--text, #cdd6f4);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.content-badge[data-v-929d4ed2]{font-size:.7em;text-transform:uppercase;padding:2px 8px;background:var(--accent-muted, #313244);color:var(--accent, #4ec9b0)}.content-actions[data-v-929d4ed2]{display:inline-flex;align-items:center;gap:4px}.content-actions a[data-v-929d4ed2],.content-actions button[data-v-929d4ed2]{width:26px;height:26px;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--border, #2a2a3e);background:var(--surface-elevated, #242438);color:var(--text, #cdd6f4);text-decoration:none;cursor:pointer}.content-actions a[data-v-929d4ed2]:hover,.content-actions button[data-v-929d4ed2]:hover{color:var(--accent, #4ec9b0);border-color:var(--accent, #4ec9b0)}.content-chevron[data-v-929d4ed2]{transition:transform .2s;color:var(--text-muted, #6c7086)}.content-card[open] .content-chevron[data-v-929d4ed2]{transform:rotate(180deg)}.content-body[data-v-929d4ed2]{border-top:1px solid var(--border, #2a2a3e);overflow:auto}.content-iframe[data-v-929d4ed2]{width:100%;height:300px;border:none;display:block}@media(min-width:768px){.content-iframe[data-v-929d4ed2]{height:500px}}.content-image[data-v-929d4ed2]{width:100%;max-height:60vh;object-fit:contain;cursor:zoom-in;display:block;background:var(--surface, #1e1e2e)}.content-video[data-v-929d4ed2]{width:100%;max-height:60vh;display:block;background:var(--surface, #1e1e2e)}.content-source[data-v-929d4ed2]{max-height:500px;overflow:auto;background:#11111b}.content-source-code[data-v-929d4ed2],.content-source-error[data-v-929d4ed2]{margin:0;padding:14px;white-space:pre;font-family:IBM Plex Mono,monospace;font-size:12px;line-height:1.6;color:var(--text, #cdd6f4)}.content-source-error[data-v-929d4ed2]{color:var(--error, #f7768e)}.content-source-state[data-v-929d4ed2]{display:flex;align-items:center;gap:8px;padding:14px;color:var(--text-muted, #6c7086);font-size:12px}.content-unknown[data-v-929d4ed2]{padding:24px;text-align:center;color:var(--text-muted, #6c7086);display:flex;flex-direction:column;align-items:center;gap:10px}.unknown-icon[data-v-929d4ed2]{font-size:2em;line-height:1}.unknown-name[data-v-929d4ed2]{font-size:.95em;font-weight:500;color:var(--text, #cdd6f4);word-break:break-word;max-width:100%}.unknown-open[data-v-929d4ed2]{display:inline-block;margin-top:4px;padding:6px 14px;border-radius:0;background:var(--accent-muted, #313244);color:var(--accent, #4ec9b0);text-decoration:none;font-size:.85em;font-weight:500;transition:background .15s}.unknown-open[data-v-929d4ed2]:hover{background:var(--border, #2a2a3e)}.content-card.is-stl .content-badge[data-v-929d4ed2]{color:#f5c2e7}.content-card.is-html .content-badge[data-v-929d4ed2]{color:#89b4fa}.content-card.is-svg .content-badge[data-v-929d4ed2]{color:#a6e3a1}.content-card.is-pdf .content-badge[data-v-929d4ed2]{color:#fab387}.content-card.is-image .content-badge[data-v-929d4ed2]{color:#89dceb}.content-card.is-video .content-badge[data-v-929d4ed2]{color:#f38ba8}.stream-cursor[data-v-d30b3b02]{display:inline-block;width:2px;height:1em;background:currentColor;margin-left:2px;vertical-align:text-bottom;animation:blink-d30b3b02 1s step-end infinite}@keyframes blink-d30b3b02{0%,to{opacity:1}50%{opacity:0}}.msg-rate-btn[data-v-d30b3b02]{opacity:.55;transition:opacity .15s,color .15s}.msg-rate-btn[data-v-d30b3b02]:hover{opacity:1}.msg-rate-btn.active[data-v-d30b3b02]{opacity:1;color:var(--accent, #4ec9b0)}.message-list-wrap[data-v-63209869]{flex:1;min-height:0;position:relative;display:flex;flex-direction:column}.messages-group[data-v-63209869]{display:flex;flex-direction:column;gap:32px}.scroll-to-bottom-btn[data-v-63209869]{position:absolute;bottom:16px;right:16px;width:40px;height:40px;border-radius:50%;background:var(--color-secondary, #7aa2f7);color:var(--color-black, #1a1b2e);border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:18px;box-shadow:0 2px 12px #0006;opacity:.9;transition:opacity .15s ease,transform .15s ease;z-index:10}.scroll-to-bottom-btn[data-v-63209869]:hover{opacity:1;transform:translateY(-2px)}.scroll-btn-enter-active[data-v-63209869],.scroll-btn-leave-active[data-v-63209869]{transition:opacity .2s ease,transform .2s ease}.scroll-btn-enter-from[data-v-63209869],.scroll-btn-leave-to[data-v-63209869]{opacity:0;transform:translateY(8px)}.file-preview-image[data-v-0239fe0c]{position:relative}.file-preview-image .file-preview-remove[data-v-0239fe0c]{position:absolute;top:-4px;right:-4px;background:var(--surface-panel, #1f2335);border:1px solid var(--border-color-muted);width:18px;height:18px;display:flex;align-items:center;justify-content:center;font-size:10px;cursor:pointer;color:var(--color-text-dark)}.file-preview-image .file-preview-remove[data-v-0239fe0c]:hover{color:var(--color-error)}.reconnect-notice[data-v-8e422257]{display:flex;align-items:center;gap:6px;padding:4px 8px;font-size:12px;color:var(--color-warning, #e0af68);margin-bottom:4px}.reconnect-banner[data-v-1f31beae]{display:flex;align-items:center;gap:8px;padding:6px 16px;background:#e0af681a;border-bottom:1px solid rgba(224,175,104,.3);font-size:13px;color:var(--color-warning, #e0af68)}.app-shell[data-v-c09e29fe]{display:flex;flex:1 1 0;min-height:0;min-width:0;overflow:hidden}.sidebar-backdrop[data-v-c09e29fe]{display:none;position:fixed;top:0;right:0;bottom:0;left:0;background:#0009;z-index:99}@media(max-width:1280px){.sidebar-backdrop[data-v-c09e29fe]{display:block}}.artifacts-backdrop[data-v-c09e29fe]{display:none;position:fixed;top:0;right:0;bottom:0;left:0;background:#00000073;z-index:119}@media(max-width:980px){.artifacts-backdrop[data-v-c09e29fe]{display:block}}.backdrop-fade-enter-active[data-v-c09e29fe],.backdrop-fade-leave-active[data-v-c09e29fe]{transition:opacity .18s ease}.backdrop-fade-enter-from[data-v-c09e29fe],.backdrop-fade-leave-to[data-v-c09e29fe]{opacity:0}@font-face{font-family:IBM Plex Mono;src:url(/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Regular.ttf) format("truetype");font-weight:400;font-style:normal;font-display:swap}@font-face{font-family:IBM Plex Mono;src:url(/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Medium.ttf) format("truetype");font-weight:500;font-style:normal;font-display:swap}@font-face{font-family:IBM Plex Mono;src:url(/assets/fonts/IBM_Plex_Mono/IBMPlexMono-SemiBold.ttf) format("truetype");font-weight:600;font-style:normal;font-display:swap}@font-face{font-family:IBM Plex Mono;src:url(/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Bold.ttf) format("truetype");font-weight:700;font-style:normal;font-display:swap}@font-face{font-family:IBM Plex Mono;src:url(/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Italic.ttf) format("truetype");font-weight:400;font-style:italic;font-display:swap}.container{padding:18px}.section{margin-bottom:48px}.section-title,.block{margin-bottom:34px}.block-title{margin-bottom:22px}p,.text{margin-bottom:15px}.hint{margin-top:8px}.list{padding-left:22px;margin-bottom:15px}.list-item{margin-bottom:8px}.list-nested{margin-top:8px}.table{margin-bottom:22px}.table-caption{margin-bottom:8px}.form-group{margin-bottom:15px}.label{margin-bottom:5px;display:block}.input,.textarea,.select{margin-top:5px}.toast{padding:15px}.toast-stack{gap:8px}@keyframes terminal_scan_x{0%{transform:translate(-120%)}to{transform:translate(220%)}}@keyframes terminal_scan_y{0%{transform:translateY(-120%)}to{transform:translateY(220%)}}@keyframes terminal_pulse{0%,to{box-shadow:0 0 #c0caf500}50%{box-shadow:0 0 0 4px #c0caf52e}}@keyframes panel_boot{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes overlay_reveal{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}@keyframes tooltip_reveal{0%{opacity:0;transform:translate(-50%) translateY(5px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important;transition-duration:.01ms!important}}html{font-size:100%}body{font-family:IBM Plex Mono,monospace;font-size:15px;font-weight:400;line-height:1.6;letter-spacing:0;color:#c0caf5}h1,h2,h3,h4,h5,h6{font-family:IBM Plex Mono,monospace;font-weight:600;line-height:1.25;margin:0}h1.contrast,h2.contrast,h3.contrast,h4.contrast,h5.contrast,h6.contrast{background:#c0caf5;color:#16161e;display:inline;padding:0 8px}h1{font-size:34px;letter-spacing:0}h2{font-size:26px}h3{font-size:22px}h4{font-size:20px}h5{font-size:18px}h6{font-size:16px;font-weight:500}.text,p{font-size:15px;line-height:1.6}.text-sm{font-size:13px;line-height:1.4}.text-lg{font-size:16px;line-height:1.6}.text-lead{max-width:760px;color:#c0caf5;font-size:16px;font-weight:500;line-height:1.6}.text-muted{font-size:13px;color:#787c99}.text-strong,strong{font-weight:600}.text-bold{font-weight:700}.text-italic,em{font-style:italic}.text-success{color:#9ece6a}.text-warning{color:#e0af68}.text-danger,.text-error{color:#f7768e}.text-info{color:#bb9af7}.eyebrow{display:inline-flex;width:max-content;max-width:100%;padding:5px 8px;color:#16161e;background:#7aa2f7;font-size:12px;font-weight:700;line-height:1;text-transform:uppercase}.caption{color:#787c99;font-size:12px;line-height:1.4}code,pre,.code{font-family:IBM Plex Mono,monospace;font-size:15px;line-height:1.4;background-color:#1f2335}.text-primary{color:#c0caf5}.text-secondary{color:#a9b1d6}pre{font-size:15px;line-height:1.6;white-space:pre-wrap}pre code,.code{tab-size:2;-moz-tab-size:2}.code{display:inline-flex;padding:0 5px;color:#7aa2f7;border:2px solid rgba(122,162,247,.24)}.kbd{display:inline-flex;align-items:center;min-height:24px;padding:0 8px;border:2px solid rgba(192,202,245,.24);border-bottom-color:#7aa2f7;color:#c0caf5;background:#c0caf50b;font-family:IBM Plex Mono,monospace;font-size:12px;font-weight:700;line-height:1;text-transform:uppercase}.quote{max-width:760px;margin:0;padding:15px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;color:#a9b1d6;background:#c0caf50b;font-size:15px;line-height:1.6}.quote cite{display:block;margin-top:12px;color:#7aa2f7;font-size:13px;font-style:normal;text-transform:uppercase}a{font-weight:500;text-decoration:none;color:#7aa2f7}@media(hover:hover)and (pointer:fine){a:hover{color:#e0af68}}@media(hover:none)and (pointer:coarse){a:active{color:#e0af68}}.link{font-size:inherit;font-weight:500}.label{font-size:13px;font-weight:500;line-height:1.4}.hint,.meta{font-size:12px;line-height:1.4}.table{font-size:13px;line-height:1.4}.table th{font-weight:600}.table td{font-weight:400}.list{font-size:15px;line-height:1.6}.list-item{font-size:inherit}.modal-title{font-size:20px;font-weight:600}.modal-body{font-size:15px}.toast-title{font-size:14px;font-weight:600}.toast-text{font-size:13px;line-height:1.4}.palette{display:flex;flex-direction:row;flex-wrap:wrap;gap:8px}.palette .color .color-box{width:92px;height:68px}body .bg-primary{background:#c0caf5}body .bg-secondary{background:#7aa2f7}body .bg-success{background:#9ece6a}body .bg-accent{background:#ff9e64}body .bg-info{background:#bb9af7}body .bg-warning{background:#e0af68}body .bg-error{background:#f7768e}body .text-color-primary{color:#c0caf5}body .text-color-secondary{color:#7aa2f7}body .text-color-success{color:#9ece6a}body .text-color-accent{color:#ff9e64}body .text-color-info{color:#bb9af7}body .text-color-warning{color:#e0af68}body .text-color-error{color:#f7768e}.loader{width:32px;aspect-ratio:1;--c:no-repeat linear-gradient(#FF3C00 0 0);background:var(--c) 0 0,var(--c) 0 100%,var(--c) 50% 0,var(--c) 50% 100%,var(--c) 100% 0,var(--c) 100% 100%;animation:l12 1s infinite}@keyframes l12{0%,to{background-size:20% 50%}16.67%{background-size:20% 30%,20% 30%,20% 50%,20% 50%,20% 50%,20% 50%}33.33%{background-size:20% 30%,20% 30%,20% 30%,20% 30%,20% 50%,20% 50%}50%{background-size:20% 30%,20% 30%,20% 30%,20% 30%,20% 30%,20% 30%}66.67%{background-size:20% 50%,20% 50%,20% 30%,20% 30%,20% 30%,20% 30%}83.33%{background-size:20% 50%,20% 50%,20% 50%,20% 50%,20% 30%,20% 30%}}.circle-loader{display:flex;flex-direction:row;align-items:center;gap:8px}.circle-loader .ph,.circle-loader .ph-bold{font-size:26px;transform-origin:50% 50%;animation:icon_spin 1.2s linear infinite}.progress{display:flex;flex-direction:column;gap:8px;width:100%;max-width:640px}.progress .progress-header{display:flex;align-items:center;justify-content:space-between;gap:12px;color:#a9b1d6;font-size:13px;font-weight:600;text-transform:uppercase}.progress .progress-value{color:#c0caf5;font-family:IBM Plex Mono,monospace}.progress .progress-track{position:relative;width:100%;height:18px;overflow:hidden;border:2px solid rgba(192,202,245,.24);background:#c0caf50b}.progress .progress-bar{display:block;position:relative;overflow:hidden;width:var(--progress-value, 0%);height:100%;background:#7aa2f7;transition:width .28s ease}.progress.progress-success .progress-bar{background:#9ece6a}.progress.progress-warning .progress-bar{background:#e0af68}.progress.progress-danger .progress-bar,.progress.progress-error .progress-bar{background:#f7768e}.progress.progress-striped .progress-bar{background-image:repeating-linear-gradient(90deg,transparent 0,transparent 14px,rgba(22,22,30,.2) 14px,rgba(22,22,30,.2) 16px)}.progress.progress-animated .progress-bar:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;width:48%;background:linear-gradient(90deg,transparent,rgba(192,202,245,.28),transparent);transform:translate(-120%);animation:progress_scan 1.4s ease infinite}.usage-meter{display:grid;gap:12px;width:100%;max-width:420px;padding:15px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#c0caf50b}.usage-meter .usage-meter-title{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:0;font-size:16px;font-weight:700;line-height:1;text-transform:uppercase}.usage-meter .usage-meter-value{color:#7aa2f7;font-family:IBM Plex Mono,monospace;font-size:13px}.usage-meter .usage-meter-meta{margin:0;color:#a9b1d6;font-size:13px;line-height:1.4}.progress-stages{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;width:100%;max-width:720px}.progress-stages .progress-stage{min-height:42px;padding:8px 12px;border:2px solid rgba(192,202,245,.24);color:#787c99;background:#c0caf50b;font-size:13px;font-weight:600;line-height:1.4;text-transform:uppercase}.progress-stages .progress-stage-complete{color:#16161e;background:#9ece6a;border-color:#9ece6a}.progress-stages .progress-stage-current{color:#16161e;background:#e0af68;border-color:#e0af68}@media(max-width:767px){.progress-stages{grid-template-columns:1fr 1fr}}@media(max-width:479px){.progress-stages{grid-template-columns:1fr}}@keyframes progress_scan{0%{transform:translate(-120%)}to{transform:translate(220%)}}@keyframes icon_spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.btn{display:inline-flex;align-items:center;justify-content:center;min-height:46px;font-family:IBM Plex Mono,monospace;font-size:15px;font-weight:600;line-height:1;letter-spacing:.04em;padding:12px 22px;border-radius:0;border-width:2px;border-left-width:6px;border-style:solid;border-color:#c0caf5;text-transform:uppercase;background-color:transparent;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:background-color,border-color,color,opacity}.btn:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}.btn.with-icon{border-left-width:46px;position:relative}.btn.with-icon .ph,.btn.with-icon .ph-bold{position:absolute;color:#16161e;left:-46px;top:1px;font-size:26px;height:100%;display:inline-flex;align-items:center;width:46px;justify-content:center;transition-duration:.2s;transition-property:color,left}@media(hover:hover)and (pointer:fine){.btn:hover.with-icon:not(.loading-state):not(.btn-small) .ph,.btn:hover.with-icon:not(.loading-state):not(.btn-small) .ph-bold{left:-28px}}@media(hover:none)and (pointer:coarse){.btn:active.with-icon:not(.loading-state):not(.btn-small) .ph,.btn:active.with-icon:not(.loading-state):not(.btn-small) .ph-bold{left:-28px}}.btn.btn-primary{color:#c0caf5;border-color:#c0caf5}@media(hover:hover)and (pointer:fine){.btn.btn-primary:hover{background-color:#c0caf5;color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-primary:active{background-color:#c0caf5;color:#16161e}}.btn.btn-secondary{color:#7aa2f7;border-color:#7aa2f7}@media(hover:hover)and (pointer:fine){.btn.btn-secondary:hover{background-color:#7aa2f7;color:#16161e}.btn.btn-secondary:hover.with-icon .ph,.btn.btn-secondary:hover.with-icon .ph-bold{color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-secondary:active{background-color:#7aa2f7;color:#16161e}.btn.btn-secondary:active.with-icon .ph,.btn.btn-secondary:active.with-icon .ph-bold{color:#16161e}}.btn.btn-accent{color:#ff9e64;border-color:#ff9e64}@media(hover:hover)and (pointer:fine){.btn.btn-accent:hover{background-color:#ff9e64;color:#16161e}.btn.btn-accent:hover.with-icon .ph,.btn.btn-accent:hover.with-icon .ph-bold{color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-accent:active{background-color:#ff9e64;color:#16161e}.btn.btn-accent:active.with-icon .ph,.btn.btn-accent:active.with-icon .ph-bold{color:#16161e}}.btn.btn-danger{color:#f7768e;border-color:#f7768e}@media(hover:hover)and (pointer:fine){.btn.btn-danger:hover{background-color:#f7768e;color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-danger:active{background-color:#f7768e;color:#16161e}}.btn.btn-warning{color:#e0af68;border-color:#e0af68}@media(hover:hover)and (pointer:fine){.btn.btn-warning:hover{background-color:#e0af68;color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-warning:active{background-color:#e0af68;color:#16161e}}.btn.btn-success{color:#9ece6a;border-color:#9ece6a}@media(hover:hover)and (pointer:fine){.btn.btn-success:hover{background-color:#9ece6a;color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-success:active{background-color:#9ece6a;color:#16161e}}.btn.btn-info{color:#bb9af7;border-color:#bb9af7}@media(hover:hover)and (pointer:fine){.btn.btn-info:hover{background-color:#bb9af7;color:#16161e}.btn.btn-info:hover.with-icon .ph,.btn.btn-info:hover.with-icon .ph-bold{color:#16161e}}@media(hover:none)and (pointer:coarse){.btn.btn-info:active{background-color:#bb9af7;color:#16161e}.btn.btn-info:active.with-icon .ph,.btn.btn-info:active.with-icon .ph-bold{color:#16161e}}.btn[disabled]:not(.loading-state){color:#787c99;border-color:#c0caf53d;background-color:#1f2335;cursor:not-allowed;opacity:.72}.btn[disabled]:not(.loading-state).with-icon .ph,.btn[disabled]:not(.loading-state).with-icon .ph-bold{color:#787c99}@media(hover:hover)and (pointer:fine){.btn[disabled]:not(.loading-state):hover{background-color:#1f2335;color:#787c99}.btn[disabled]:not(.loading-state):hover.with-icon .ph,.btn[disabled]:not(.loading-state):hover.with-icon .ph-bold{color:#787c99}}@media(hover:none)and (pointer:coarse){.btn[disabled]:not(.loading-state):active{background-color:#1f2335;color:#787c99}.btn[disabled]:not(.loading-state):active.with-icon .ph,.btn[disabled]:not(.loading-state):active.with-icon .ph-bold{color:#787c99}}.btn[disabled]:not(.loading-state).with-icon:not(.btn-small) .ph,.btn[disabled]:not(.loading-state).with-icon:not(.btn-small) .ph-bold{left:-28px}.btn.btn-small{font-size:13px;font-weight:500;min-height:38px;padding:8px}.btn.btn-small.with-icon{border-left-width:32px}.btn.btn-small.with-icon .ph,.btn.btn-small.with-icon .ph-bold{top:0;left:-40px;font-size:22px}.btn.btn-small.with-icon.loading-state .ph,.btn.btn-small.with-icon.loading-state .ph-bold{font-size:26px}.btn.btn-large{font-size:16px;font-weight:700;min-height:54px;padding:15px 48px}.btn.loading-state{color:#16161e!important;border-color:#c0caf5!important;background-color:#c0caf5!important}.btn.loading-state .ph,.btn.loading-state .ph-bold{font-size:26px;transform-origin:50% 50%;animation:icon_spin 1.2s linear infinite}.btn-icon{display:flex;justify-content:center;align-items:center;width:38px;height:38px;background:transparent;color:#c0caf5;font-size:22px;border:2px solid transparent;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color}.btn-icon:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}.btn-icon .ph{transform:rotate(0);transition-duration:.2s;transition-property:transform}@media(hover:hover)and (pointer:fine){.btn-icon:not(.without-hover):hover{color:#e0af68;border-color:#e0af68}.btn-icon:not(.without-hover):hover .ph{transform:rotate(90deg)}}@media(hover:none)and (pointer:coarse){.btn-icon:not(.without-hover):active{color:#e0af68;border-color:#e0af68}.btn-icon:not(.without-hover):active .ph{transform:rotate(90deg)}}.form-group{width:100%;max-width:600px}.form-group .label{display:flex;flex-direction:column;font-size:15px;width:100%;position:relative}.form-group .label>.ph{position:absolute;color:#c0caf5;left:0;bottom:1px;font-size:26px;height:54px;display:inline-flex;align-items:center;width:46px;justify-content:center;transition-duration:.2s;transition-property:color,left}.form-group .label .input{min-height:54px;font-family:IBM Plex Mono,monospace;font-size:15px;font-weight:500;line-height:1;letter-spacing:.04em;padding:12px 22px;margin-top:8px;border-radius:0;border-width:2px;border-bottom-width:6px;border-style:solid;border-color:#c0caf5;color:#c0caf5;background-color:#c0caf50b;transition-duration:.2s;transition-timing-function:ease;transition-property:background-color,border-color,color}@media(hover:hover)and (pointer:fine){.form-group .label .input:hover{border-bottom-color:#787c99}}@media(hover:none)and (pointer:coarse){.form-group .label .input:active{border-bottom-color:#787c99}}.form-group .label .input:focus{outline:2px solid #E0AF68;outline-offset:3px;border-color:#7aa2f7;background-color:transparent}.form-group .label .input:disabled{color:#787c99;border-color:#c0caf53d;background:#1f2335;cursor:not-allowed;opacity:.72}.form-group .label .input[readonly]{color:#a9b1d6;border-color:#c0caf53d;background:#c0caf508}.form-group .label .input::placeholder{color:#787c99}.form-group .label .input::-webkit-search-cancel-button,.form-group .label .input::-webkit-search-decoration,.form-group .label .input::-webkit-search-results-button,.form-group .label .input::-webkit-search-results-decoration{display:none;-webkit-appearance:none}.form-group .label .input[type=date],.form-group .label .input[type=time],.form-group .label .input[type=datetime-local],.form-group .label .input[type=month]{color-scheme:dark;cursor:pointer;min-width:0;padding-right:46px;text-transform:uppercase}.form-group .label .input[type=date]::-webkit-calendar-picker-indicator,.form-group .label .input[type=time]::-webkit-calendar-picker-indicator,.form-group .label .input[type=datetime-local]::-webkit-calendar-picker-indicator,.form-group .label .input[type=month]::-webkit-calendar-picker-indicator{width:46px;height:100%;margin:0;padding:0;background:transparent;cursor:pointer;opacity:0}.form-group .label .input[type=date]::-webkit-datetime-edit,.form-group .label .input[type=time]::-webkit-datetime-edit,.form-group .label .input[type=datetime-local]::-webkit-datetime-edit,.form-group .label .input[type=month]::-webkit-datetime-edit{padding:0}.form-group .label .input[type=date]::-webkit-datetime-edit-fields-wrapper,.form-group .label .input[type=time]::-webkit-datetime-edit-fields-wrapper,.form-group .label .input[type=datetime-local]::-webkit-datetime-edit-fields-wrapper,.form-group .label .input[type=month]::-webkit-datetime-edit-fields-wrapper{color:#c0caf5}.form-group .label textarea.input{height:108px;line-height:1.25;resize:none}.form-group .label .ph+.input,.form-group .label .ph+.select-wrap .select{padding-left:46px}.form-group .label .select-wrap{margin-top:8px}.form-group .label .select{width:100%;height:54px;margin-top:0;appearance:none;-webkit-appearance:none;-moz-appearance:none}.form-group .label .select:focus{outline:none}.form-group .label .select option{color:#c0caf5;background:#1f2335}.form-group .label .select-wrap:after{content:"";position:absolute;right:22px;bottom:18px;transform:translateY(-50%);width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:10px solid #C0CAF5;pointer-events:none}.form-group .label.error .input:not(:focus){border-color:#f7768e}.form-group .label.error+.input-info{color:#e0af68}.form-group .label.success .input:not(:focus){border-color:#9ece6a}.form-group .label.success+.input-info{color:#9ece6a}.form-group .label.warning .input:not(:focus){border-color:#e0af68}.form-group .label.warning+.input-info{color:#e0af68}.form-group .input-info{font-size:14px;margin-top:8px}.form-group .input-info .ph{position:relative;top:1px}.form-group .input-info.error{color:#e0af68}.form-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:15px;width:100%;max-width:760px}.fieldset{width:100%;max-width:760px;margin:0;padding:18px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#c0caf50b}.legend{padding:5px 8px;color:#16161e;background:#c0caf5;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase}.file-upload{display:inline-flex;align-items:center;gap:8px;min-height:46px;padding:8px 12px;border:2px solid #7AA2F7;border-left-width:6px;color:#7aa2f7;background:#c0caf50b;font-size:13px;font-weight:700;text-transform:uppercase;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color}.file-upload input[type=file]{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}@media(hover:hover)and (pointer:fine){.file-upload:hover{color:#16161e;background:#7aa2f7}}@media(hover:none)and (pointer:coarse){.file-upload:active{color:#16161e;background:#7aa2f7}}.file-upload:focus-within{outline:2px solid #E0AF68;outline-offset:3px}.file-upload-panel{width:100%;max-width:760px;background:#c0caf50b;border:2px solid rgba(192,202,245,.24);border-left-width:6px}.file-upload-form{display:flex;flex-direction:column;gap:15px;margin:0}.file-upload-header{display:flex;align-items:flex-start;justify-content:space-between;gap:15px;padding:15px 15px 0}.file-upload-heading{display:flex;flex-direction:column;gap:5px;min-width:0}.file-upload-title{margin:0;color:#c0caf5;font-size:16px;font-weight:700;line-height:1.25;text-transform:uppercase}.file-upload-description{margin:0;color:#a9b1d6;font-size:13px;line-height:1.6}.file-upload-dropzone{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:15px;margin:0 15px;padding:18px;border:2px dashed #7AA2F7;background:#7aa2f714;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:background,border-color}.file-upload-dropzone input[type=file]{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}@media(hover:hover)and (pointer:fine){.file-upload-dropzone:hover{border-color:#c0caf5;background:#c0caf51a}}@media(hover:none)and (pointer:coarse){.file-upload-dropzone:active{border-color:#c0caf5;background:#c0caf51a}}.file-upload-dropzone:focus-within{outline:2px solid #E0AF68;outline-offset:3px}.file-upload-icon{display:inline-flex;align-items:center;justify-content:center;width:54px;height:54px;color:#16161e;background:#7aa2f7;font-size:26px}.file-upload-body{display:flex;flex-direction:column;gap:5px;min-width:0}.file-upload-primary{color:#c0caf5;font-size:15px;font-weight:700;line-height:1.25;text-transform:uppercase}.file-upload-secondary{color:#a9b1d6;font-size:13px;line-height:1.4}.file-upload-preview{display:grid;grid-template-columns:repeat(auto-fill,minmax(148px,1fr));gap:12px;margin:0 15px}.file-upload-preview[hidden]{display:none}.file-upload-preview-item{position:relative;min-width:0;margin:0;border:2px solid rgba(192,202,245,.24);background:#c0caf50b}.file-upload-preview-remove{position:absolute;top:8px;right:8px;z-index:1;display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:2px solid #F7768E;color:#f7768e;background:#1f2335;font-size:18px;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color}@media(hover:hover)and (pointer:fine){.file-upload-preview-remove:hover{color:#16161e;background:#f7768e}}@media(hover:none)and (pointer:coarse){.file-upload-preview-remove:active{color:#16161e;background:#f7768e}}.file-upload-preview-remove:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}.file-upload-preview-visual{display:flex;align-items:center;justify-content:center;aspect-ratio:1;background:#1f2335}.file-upload-preview-visual img{display:block;width:100%;height:100%;object-fit:cover}.file-upload-preview-type{display:inline-flex;align-items:center;justify-content:center;min-width:54px;min-height:54px;padding:8px;color:#16161e;background:#7aa2f7;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase}.file-upload-preview-item figcaption{display:flex;flex-direction:column;gap:5px;overflow:hidden;padding:8px}.file-upload-preview-name{overflow:hidden;color:#c0caf5;font-size:12px;font-weight:700;line-height:1.25;text-overflow:ellipsis;white-space:nowrap}.file-upload-preview-meta{color:#a9b1d6;font-size:12px;font-weight:700;line-height:1.25;text-transform:uppercase}.file-upload-actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px;padding:0 15px 15px}.range{width:100%;max-width:600px;accent-color:#7AA2F7}.range input[type=range]{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:100%;height:46px;margin:0;background:transparent;cursor:pointer}.range input[type=range]::-webkit-slider-runnable-track{height:6px;background:#c0caf516;border:2px solid rgba(192,202,245,.24)}.range input[type=range]::-webkit-slider-thumb{width:18px;height:38px;margin-top:-19px;border:2px solid #7AA2F7;background:#7aa2f7;-webkit-appearance:none}.range input[type=range]::-moz-range-track{height:6px;background:#c0caf516;border:2px solid rgba(192,202,245,.24)}.range input[type=range]::-moz-range-thumb{width:18px;height:38px;border:2px solid #7AA2F7;border-radius:0;background:#7aa2f7}@media(max-width:767px){.form-grid{grid-template-columns:1fr}.file-upload-header{flex-direction:column;align-items:stretch}.file-upload-dropzone{grid-template-columns:1fr}.file-upload-actions{justify-content:stretch}.file-upload-actions .btn{width:100%}}.radio{display:inline-flex;flex-direction:row;gap:8px;align-items:center}.radio input[type=radio]{display:none}.radio .radio-control{display:inline-block;border-radius:100%;border:2px solid #C0CAF5;width:18px;height:18px;background:transparent;transition-duration:.2s;transition-property:background,border-color}@media(hover:hover)and (pointer:fine){.radio:hover .radio-control{background:#414868}}@media(hover:none)and (pointer:coarse){.radio:active .radio-control{background:#414868}}.radio input[type=radio]:checked+.radio-control{background:#c0caf5}.radio input[type=radio]:disabled+.radio-control{background:#414868;border-color:#414868}.radio input[type=radio]:focus-visible+.radio-control{outline:2px solid #E0AF68;outline-offset:3px}.radio .radio-label{font-size:15px}.checkbox{display:inline-flex;flex-direction:row;gap:8px;align-items:center}.checkbox input[type=checkbox]{display:none}.checkbox .checkbox-control{height:16px;width:32px;border:2px solid #C0CAF5;position:relative;background:transparent;transition-duration:.2s;transition-property:border-color,background;display:block}.checkbox .checkbox-control:before{content:"";display:block;height:20px;width:20px;background:#c0caf5;position:absolute;left:-5px;top:-5px;transition-duration:.2s;transition-property:left,background}@media(hover:hover)and (pointer:fine){.checkbox:hover .checkbox-control{background:#414868}}@media(hover:none)and (pointer:coarse){.checkbox:active .checkbox-control{background:#414868}}.checkbox input[type=checkbox]:checked:not(:disabled)+.checkbox-control{background:#7aa2f7;border-color:#7aa2f7}.checkbox input[type=checkbox]:checked+.checkbox-control:before{left:17px}.checkbox input[type=checkbox]:disabled+.checkbox-control{border-color:#414868}.checkbox input[type=checkbox]:focus-visible+.checkbox-control{outline:2px solid #E0AF68;outline-offset:3px}.checkbox input[type=checkbox]:disabled+.checkbox-control:before{background:#414868}.input-group{display:flex;align-items:stretch;width:100%;max-width:600px;min-height:54px;border:2px solid #C0CAF5;border-bottom-width:6px;background:#c0caf50b;transition-duration:.2s;transition-timing-function:ease;transition-property:border-color,background}.input-group:focus-within{outline:2px solid #E0AF68;outline-offset:3px;border-color:#7aa2f7;background:transparent}.input-group .input-group-addon,.input-group .input-group-action{display:inline-flex;align-items:center;justify-content:center;min-width:54px;padding:0 12px;color:#a9b1d6;background:#c0caf50b;border:0;font-family:IBM Plex Mono,monospace;font-size:13px;font-weight:600;text-transform:uppercase}.input-group .input-group-action{color:#c0caf5;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background}@media(hover:hover)and (pointer:fine){.input-group .input-group-action:hover{color:#16161e;background:#e0af68}}@media(hover:none)and (pointer:coarse){.input-group .input-group-action:active{color:#16161e;background:#e0af68}}.input-group .input-group-input{flex:1 1 auto;min-width:0;border:0;padding:12px 15px;color:#c0caf5;background:transparent;font-family:IBM Plex Mono,monospace;font-size:15px;font-weight:500;letter-spacing:.04em}.input-group .input-group-input:focus{outline:none}.input-group .input-group-input::placeholder{color:#787c99}.input-group .input-group-input::-webkit-search-cancel-button,.input-group .input-group-input::-webkit-search-decoration,.input-group .input-group-input::-webkit-search-results-button,.input-group .input-group-input::-webkit-search-results-decoration{display:none;-webkit-appearance:none}.input-group .ph,.input-group .ph-bold{font-size:22px}.input-group.input-group-compact{min-height:46px}.input-group.input-group-compact .input-group-addon,.input-group.input-group-compact .input-group-action{min-width:46px}.input-group.input-group-compact .input-group-input{padding:8px 12px;font-size:13px}.search-field{max-width:420px}.list{display:flex;flex-direction:column;gap:5px;list-style-type:none;padding-left:0}.list .list-item{display:flex;flex-direction:row;align-items:center;gap:8px;margin-left:0}.list.list-ordered{list-style-type:decimal;display:list-item;margin-left:30px}.list.list-ordered .list-item{display:list-item}.list.list-definition{width:100%;max-width:620px;gap:0;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#c0caf50b}.list.list-definition .list-row{display:grid;grid-template-columns:minmax(120px,.32fr) minmax(0,1fr);gap:15px;align-items:start;padding:12px 15px;border-bottom:2px solid rgba(192,202,245,.08);transition-duration:.2s;transition-timing-function:ease;transition-property:background,border-color}.list.list-definition .list-row .list-term{display:inline-flex;width:max-content;max-width:100%;margin:0;padding:5px 8px;color:#16161e;background:#c0caf5;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase;transition-duration:.2s;transition-timing-function:ease;transition-property:background,transform}.list.list-definition .list-row .list-desc{margin:0;color:#a9b1d6;font-size:13px;line-height:1.6;transition-duration:.2s;transition-timing-function:ease;transition-property:color,transform}.list.list-definition .list-row:last-child{border-bottom:0}@media(hover:hover)and (pointer:fine){.list.list-definition .list-row:hover{background:#c0caf516}.list.list-definition .list-row:hover .list-term{background:#7aa2f7;transform:translate(5px)}.list.list-definition .list-row:hover .list-desc{color:#c0caf5;transform:translate(5px)}}@media(hover:none)and (pointer:coarse){.list.list-definition .list-row:active{background:#c0caf516}.list.list-definition .list-row:active .list-term{background:#7aa2f7;transform:translate(5px)}.list.list-definition .list-row:active .list-desc{color:#c0caf5;transform:translate(5px)}}.list.list-nav{max-width:420px;width:100%;gap:0}.list.list-nav .list-item{display:flex;flex-direction:column;align-items:flex-start;height:50px;margin:0}.list.list-nav .list-item .list-action{display:flex;justify-content:space-between;align-items:center;width:100%;height:100%;padding:8px 12px;border:2px solid transparent;font-size:15px;background:#1f2335;color:inherit;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:background,border-color,color}.list.list-nav .list-item .list-action:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.list.list-nav .list-item .list-action:hover{background:#7aa2f7;color:#16161e}}@media(hover:none)and (pointer:coarse){.list.list-nav .list-item .list-action:active{background:#7aa2f7;color:#16161e}}.list.list-nav .list-item .list-action .list-label{display:flex;flex-direction:row;gap:8px;align-items:center;letter-spacing:0;font-weight:400}.list.list-nav .list-item .list-action .list-meta{padding:8px;background:#9ece6a;color:#16161e;display:flex}.list.list-nav .list-item.list-item-active .list-action{background:#7aa2f7;color:#16161e;border-color:#7aa2f7}.list.list-actions{width:100%;max-width:420px;gap:22px}.list.list-actions .list-item{justify-content:space-between;align-items:flex-start;padding:12px 0;border-bottom:2px solid rgba(192,202,245,.08)}.list.list-actions .list-item .list-content{display:flex;flex-direction:column;gap:8px}.list.list-actions .list-item .list-content .list-title{font-size:16px;line-height:1}.list.list-actions .list-item .list-content .list-subtitle{color:#787c99}@media(hover:hover)and (pointer:fine){.list.list-actions .list-item:hover .list-title{color:#7aa2f7}}@media(hover:none)and (pointer:coarse){.list.list-actions .list-item:active .list-title{color:#7aa2f7}}@media(max-width:479px){.list.list-definition .list-row{grid-template-columns:1fr;gap:8px}}.badge{position:relative;overflow:hidden;background:#c0caf5;color:#16161e;padding:5px 8px;font-size:13px;font-weight:600;line-height:1;letter-spacing:.04em;text-transform:uppercase;display:inline-flex;align-items:center;min-height:24px;transition-duration:.2s;transition-timing-function:ease;transition-property:filter,transform,border-color,color,background}.badge:after{content:"";position:absolute;inset:0 auto 0 0;width:40%;background:linear-gradient(90deg,transparent,rgba(22,22,30,.16),transparent);opacity:0;pointer-events:none;transform:translate(-120%)}@media(hover:hover)and (pointer:fine){.badge:hover{filter:saturate(1.12);transform:translateY(-1px)}.badge:hover:after{opacity:1;animation:terminal_scan_x .7s ease}}@media(hover:none)and (pointer:coarse){.badge:active{filter:saturate(1.12);transform:translateY(-1px)}.badge:active:after{opacity:1;animation:terminal_scan_x .7s ease}}.badge.badge-success{background:#9ece6a}.badge.badge-warning{background:#e0af68}.badge.badge-error,.badge.badge-danger{background:#f7768e}.badge.badge-info{background:#bb9af7;color:#16161e}.badge.badge-secondary{background:#7aa2f7;color:#16161e}.badge.badge-primary-outline{color:#c0caf5;border:2px solid #C0CAF5;background:transparent;padding:3px 8px}.chip-group{display:flex;flex-wrap:wrap;gap:8px;align-items:center}.chip{display:inline-flex;align-items:center;gap:8px;min-height:30px;padding:5px 12px;border:2px solid rgba(192,202,245,.24);color:#a9b1d6;background:#c0caf50b;font-family:IBM Plex Mono,monospace;font-size:12px;font-weight:600;line-height:1;text-transform:uppercase;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color,opacity}.chip .ph,.chip .ph-bold{font-size:18px}.chip:before{content:"";display:inline-block;width:7px;height:7px;flex:0 0 auto;background:#787c99;transition-duration:.2s;transition-timing-function:ease;transition-property:background,box-shadow,transform}.chip:has(.ph):before,.chip:has(.ph-bold):before{display:none}.chip .chip-remove{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;margin-right:-5px;border:0;color:inherit;background:transparent;font:inherit;cursor:pointer}.chip .chip-remove:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}.chip.chip-primary{color:#c0caf5;background:#c0caf514;border-color:#c0caf5}.chip.chip-primary:before{background:#c0caf5}.chip.chip-secondary{color:#7aa2f7;background:#7aa2f714;border-color:#7aa2f7}.chip.chip-secondary:before{background:#7aa2f7}.chip.chip-success{color:#9ece6a;background:#9ece6a14;border-color:#9ece6a}.chip.chip-success:before{background:#9ece6a}.chip.chip-warning{color:#e0af68;background:#e0af6814;border-color:#e0af68}.chip.chip-warning:before{background:#e0af68}.chip.chip-danger,.chip.chip-error{color:#f7768e;background:#f7768e14;border-color:#f7768e}.chip.chip-danger:before,.chip.chip-error:before{background:#f7768e}.chip.chip-selected,.chip[aria-pressed=true],.chip[aria-selected=true]{color:#16161e;background:#c0caf5;border-color:#c0caf5}.chip.chip-selected:before,.chip[aria-pressed=true]:before,.chip[aria-selected=true]:before{background:#16161e}.chip.chip-selected.chip-secondary,.chip.chip-secondary[aria-pressed=true],.chip.chip-secondary[aria-selected=true]{background:#7aa2f7;border-color:#7aa2f7}.chip.chip-disabled,.chip:disabled{color:#787c99;background:#1f2335;border-color:#c0caf53d;cursor:not-allowed;opacity:.7}.chip.chip-disabled:before,.chip:disabled:before{background:#414868}button.chip,a.chip{cursor:pointer}button.chip:focus-visible,a.chip:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){button.chip:hover,a.chip:hover{color:#c0caf5;background:#c0caf516;border-color:#7aa2f7}button.chip:hover:before,a.chip:hover:before{background:#7aa2f7;animation:terminal_pulse .7s ease;transform:scale(1.12)}}@media(hover:none)and (pointer:coarse){button.chip:active,a.chip:active{color:#c0caf5;background:#c0caf516;border-color:#7aa2f7}button.chip:active:before,a.chip:active:before{background:#7aa2f7;animation:terminal_pulse .7s ease;transform:scale(1.12)}}.avatar{position:relative;display:inline-flex;align-items:center;justify-content:center;width:46px;height:46px;flex:0 0 auto;overflow:hidden;border:2px solid rgba(192,202,245,.24);color:#16161e;background:#c0caf5;font-family:IBM Plex Mono,monospace;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase}.avatar img{width:100%;height:100%;object-fit:cover}.avatar .ph,.avatar .ph-bold{font-size:22px}.avatar .avatar-status{position:absolute;right:-2px;bottom:-2px;width:13px;height:13px;border:2px solid #16161E;background:#787c99;transition-duration:.2s;transition-timing-function:ease;transition-property:background,box-shadow}.avatar.avatar-sm{width:38px;height:38px;font-size:12px}.avatar.avatar-sm .ph,.avatar.avatar-sm .ph-bold{font-size:18px}.avatar.avatar-lg{width:54px;height:54px;font-size:14px}.avatar.avatar-lg .ph,.avatar.avatar-lg .ph-bold{font-size:26px}.avatar.avatar-secondary{background:#7aa2f7}.avatar.avatar-success{background:#9ece6a}.avatar.avatar-warning{background:#e0af68}.avatar.avatar-danger,.avatar.avatar-error{background:#f7768e}.avatar.avatar-outline{color:#c0caf5;background:#c0caf50b;border-color:#c0caf5}.avatar.is-online .avatar-status{background:#9ece6a;animation:terminal_pulse 1.8s ease infinite}.avatar.is-busy .avatar-status{background:#e0af68}.avatar.is-offline .avatar-status{background:#787c99}.identity{display:inline-flex;align-items:center;gap:12px;min-width:0}.identity-content{display:flex;flex-direction:column;gap:5px;min-width:0}.identity-title{color:#c0caf5;font-size:15px;font-weight:600;line-height:1}.identity-meta{color:#787c99;font-size:13px;line-height:1.4}.avatar-stack{display:inline-flex;align-items:center}.avatar-stack .avatar{margin-right:-8px;border-color:#16161e}.avatar-stack .avatar-stack-count{display:inline-flex;align-items:center;justify-content:center;min-width:46px;height:46px;padding:0 8px;border:2px solid #16161E;color:#16161e;background:#e0af68;font-size:13px;font-weight:700}.table{width:100%;text-align:left;border:2px solid rgba(192,202,245,.24);border-collapse:collapse;background:#c0caf50b}.table .table-caption{text-align:left;font-size:16px;background:#c0caf5;width:max-content;color:#16161e;padding:5px 12px;margin-bottom:0;font-weight:700;text-transform:uppercase}.table.table-empty{width:100%}.table.table-empty .is-empty{width:100%;padding:15px;font-size:13px;color:#787c99;text-align:left}.table .table-row th,.table .table-row td{padding:12px 18px;font-size:13px;vertical-align:middle;border-bottom:2px solid rgba(192,202,245,.08)}.table .table-row th{color:#c0caf5;background:#c0caf50a;text-transform:uppercase;letter-spacing:.04em}.table .table-head{border-bottom:2px solid #C0CAF5}.table .table-body .table-row{transition-duration:.2s;transition-timing-function:ease;transition-property:background,color}.table .table-body .table-row td{transition-duration:.2s;transition-timing-function:ease;transition-property:color,background}@media(hover:hover)and (pointer:fine){.table .table-body .table-row:hover{background:#7aa2f714}.table .table-body .table-row:hover td:first-child{color:#7aa2f7}}@media(hover:none)and (pointer:coarse){.table .table-body .table-row:active{background:#7aa2f714}.table .table-body .table-row:active td:first-child{color:#7aa2f7}}.table .table-foot th,.table .table-foot td{padding-top:15px}.table.table-compact .table-caption{font-size:14px}.table.table-compact .table-row th,.table.table-compact .table-row td{padding:8px 12px;font-size:12px}.table.table-compact .table-cell-mono{color:#a9b1d6;font-family:IBM Plex Mono,monospace;letter-spacing:0}.table.table-compact .table-cell-actions{width:1%;white-space:nowrap}.table-wrapper{width:100%;overflow-x:auto}.toolbar{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;width:100%;padding:12px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#c0caf50b}.toolbar .toolbar-group{display:flex;flex-wrap:wrap;align-items:center;gap:8px;min-width:0}.toolbar .toolbar-title{margin:0;font-size:16px;font-weight:700;line-height:1;text-transform:uppercase}.toolbar .toolbar-meta{color:#787c99;font-size:13px}.pagination{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.pagination .pagination-item{display:inline-flex;align-items:center;justify-content:center;min-width:38px;height:38px;padding:0 12px;border:2px solid rgba(192,202,245,.24);color:#a9b1d6;background:#c0caf50b;font-family:IBM Plex Mono,monospace;font-size:13px;font-weight:600;line-height:1;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color,opacity}.pagination .pagination-item:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.pagination .pagination-item:hover{color:#16161e;background:#7aa2f7;border-color:#7aa2f7}}@media(hover:none)and (pointer:coarse){.pagination .pagination-item:active{color:#16161e;background:#7aa2f7;border-color:#7aa2f7}}.pagination .pagination-item.pagination-item-active,.pagination .pagination-item[aria-current=page]{color:#16161e;background:#c0caf5;border-color:#c0caf5}.pagination .pagination-item:disabled,.pagination .pagination-item.pagination-item-disabled{color:#787c99;background:#1f2335;border-color:#c0caf53d;cursor:not-allowed;opacity:.72}.pagination .pagination-ellipsis{color:#787c99;padding:0 5px}.empty-state{max-width:560px;padding:22px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#c0caf50b}.empty-state .empty-state-icon{display:inline-flex;align-items:center;justify-content:center;width:54px;height:54px;margin-bottom:15px;color:#16161e;background:#c0caf5;font-size:26px}.empty-state .empty-state-title{margin:0 0 8px;font-size:20px;font-weight:700;text-transform:uppercase}.empty-state .empty-state-text{max-width:440px;margin:0 0 18px;color:#a9b1d6;line-height:1.6}.empty-state .empty-state-actions{display:flex;flex-wrap:wrap;gap:8px}.empty-state.empty-state-error{border-color:#f7768e}.empty-state.empty-state-error .empty-state-icon{background:#f7768e}.skeleton{display:block;position:relative;overflow:hidden;background:#c0caf516}.skeleton:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,rgba(192,202,245,.12),transparent);animation:skeleton_shimmer 1.6s infinite}.skeleton.skeleton-line{width:100%;height:14px}.skeleton.skeleton-title{width:60%;height:22px}.skeleton.skeleton-block{width:100%;height:120px}.skeleton.skeleton-square{width:54px;height:54px}.skeleton-stack{display:flex;flex-direction:column;gap:12px;max-width:520px;padding:15px;border:2px solid rgba(192,202,245,.24);background:#c0caf50b}@keyframes skeleton_shimmer{to{transform:translate(100%)}}.page-header{position:relative;display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:18px;width:100%;padding:18px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#c0caf50b;overflow:hidden;animation:panel_boot .28s ease both}.page-header:after{content:"";position:absolute;top:0;left:0;width:34%;height:2px;background:linear-gradient(90deg,transparent,#7AA2F7,transparent);opacity:.72;pointer-events:none;transform:translate(-120%)}@media(hover:hover)and (pointer:fine){.page-header:hover:after{animation:terminal_scan_x .9s ease}}@media(hover:none)and (pointer:coarse){.page-header:active:after{animation:terminal_scan_x .9s ease}}.page-header .page-header-content{display:flex;flex-direction:column;gap:8px;min-width:min(100%,320px)}.page-header .page-header-kicker{color:#7aa2f7;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase;transition-duration:.2s;transition-timing-function:ease;transition-property:color}.page-header .page-header-title{margin:0;color:#c0caf5;font-size:26px;font-weight:700;line-height:1.15}.page-header .page-header-subtitle{max-width:720px;margin:0;color:#a9b1d6;font-size:15px;line-height:1.6}.page-header .page-header-meta{display:flex;flex-wrap:wrap;align-items:center;gap:8px;color:#787c99;font-size:13px}.page-header .page-header-actions{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:8px}.page-header.page-header-compact{align-items:center;padding:15px}.page-header.page-header-compact .page-header-title{font-size:20px}.page-header.page-header-accent{border-color:#7aa2f7;background:#7aa2f70e}.description-list{display:grid;width:100%;max-width:760px;margin:0;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#c0caf50b}.description-list .description-list-row{display:grid;grid-template-columns:minmax(140px,.36fr) minmax(0,1fr);gap:15px;padding:12px 15px;border-bottom:2px solid rgba(192,202,245,.08);transition-duration:.2s;transition-timing-function:ease;transition-property:background}.description-list .description-list-row:last-child{border-bottom:0}@media(hover:hover)and (pointer:fine){.description-list .description-list-row:hover{background:#c0caf516}.description-list .description-list-row:hover .description-list-term{color:#7aa2f7}.description-list .description-list-row:hover .description-list-value{transform:translate(5px)}}@media(hover:none)and (pointer:coarse){.description-list .description-list-row:active{background:#c0caf516}.description-list .description-list-row:active .description-list-term{color:#7aa2f7}.description-list .description-list-row:active .description-list-value{transform:translate(5px)}}.description-list .description-list-term{margin:0;color:#787c99;font-size:13px;font-weight:600;line-height:1.4;text-transform:uppercase;transition-duration:.2s;transition-timing-function:ease;transition-property:color}.description-list .description-list-value{display:flex;flex-wrap:wrap;align-items:center;gap:8px;min-width:0;margin:0;color:#c0caf5;font-size:15px;line-height:1.4;transition-duration:.2s;transition-timing-function:ease;transition-property:transform}.description-list .description-list-value-muted{color:#a9b1d6}.description-list.description-list-compact{max-width:520px}.description-list.description-list-compact .description-list-row{grid-template-columns:minmax(112px,.42fr) minmax(0,1fr);gap:12px;padding:8px 12px}.description-list.description-list-compact .description-list-term,.description-list.description-list-compact .description-list-value{font-size:13px}@media(max-width:479px){.description-list .description-list-row{grid-template-columns:1fr;gap:5px}}.steps{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;width:100%;max-width:900px;margin:0;padding:0;list-style:none}.steps .step{position:relative;display:flex;flex-direction:column;gap:8px;min-height:120px;padding:15px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#c0caf50b}.steps .step-marker{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;color:#c0caf5;border:2px solid rgba(192,202,245,.24);font-size:13px;font-weight:700;line-height:1}.steps .step-title{margin:0;font-size:14px;font-weight:700;line-height:1.25;text-transform:uppercase}.steps .step-text{margin:0;color:#a9b1d6;font-size:13px;line-height:1.4}.steps .step-complete{border-color:#9ece6a}.steps .step-complete .step-marker{color:#16161e;background:#9ece6a;border-color:#9ece6a}.steps .step-current{border-color:#7aa2f7}.steps .step-current .step-marker{color:#16161e;background:#7aa2f7;border-color:#7aa2f7}.steps .step-disabled{opacity:.62}.steps.steps-vertical{grid-template-columns:1fr;max-width:520px;gap:0}.steps.steps-vertical .step{min-height:auto;border-bottom-width:0}.steps.steps-vertical .step:last-child{border-bottom-width:2px}@media(max-width:1023px){.steps{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(max-width:479px){.steps{grid-template-columns:1fr}}.timeline{display:grid;gap:0;width:100%;max-width:760px;margin:0;padding:0;list-style:none}.timeline .timeline-item{position:relative;display:grid;grid-template-columns:46px minmax(0,1fr);gap:12px;min-height:88px}.timeline .timeline-item:before{content:"";position:absolute;top:46px;bottom:0;left:22px;width:2px;background:#c0caf53d}.timeline .timeline-item:last-child:before{display:none}.timeline .timeline-marker{position:relative;z-index:1;display:inline-flex;align-items:center;justify-content:center;width:46px;height:46px;border:2px solid rgba(192,202,245,.24);color:#a9b1d6;background:#16161e;font-size:18px;transition-duration:.2s;transition-timing-function:ease;transition-property:border-color,background,color,box-shadow,transform}.timeline .timeline-content{min-width:0;padding:0 0 18px}.timeline .timeline-card{padding:15px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#c0caf50b;transition-duration:.2s;transition-timing-function:ease;transition-property:border-color,background,transform}.timeline .timeline-header{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}.timeline .timeline-title{margin:0;font-size:14px;font-weight:700;line-height:1.25;text-transform:uppercase}.timeline .timeline-time{color:#787c99;font-size:12px;font-family:IBM Plex Mono,monospace;line-height:1.4}.timeline .timeline-text{margin:0;color:#a9b1d6;font-size:13px;line-height:1.4}.timeline .timeline-meta{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.timeline .timeline-item-success .timeline-marker,.timeline .timeline-item-success .timeline-card{border-color:#9ece6a}.timeline .timeline-item-success .timeline-marker{color:#16161e;background:#9ece6a}.timeline .timeline-item-warning .timeline-marker,.timeline .timeline-item-warning .timeline-card{border-color:#e0af68}.timeline .timeline-item-warning .timeline-marker{color:#16161e;background:#e0af68}.timeline .timeline-item-danger .timeline-marker,.timeline .timeline-item-danger .timeline-card,.timeline .timeline-item-error .timeline-marker,.timeline .timeline-item-error .timeline-card{border-color:#f7768e}.timeline .timeline-item-danger .timeline-marker,.timeline .timeline-item-error .timeline-marker{color:#16161e;background:#f7768e}@media(hover:hover)and (pointer:fine){.timeline .timeline-item:hover .timeline-marker{box-shadow:0 0 0 4px #7aa2f724;transform:scale(1.04)}.timeline .timeline-item:hover .timeline-card{background:#c0caf516;transform:translate(5px)}}@media(hover:none)and (pointer:coarse){.timeline .timeline-item:active .timeline-marker{box-shadow:0 0 0 4px #7aa2f724;transform:scale(1.04)}.timeline .timeline-item:active .timeline-card{background:#c0caf516;transform:translate(5px)}}.activity-log{display:grid;width:100%;max-width:720px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#c0caf50b}.activity-log .activity-log-row{display:grid;grid-template-columns:minmax(120px,.24fr) minmax(0,1fr) auto;gap:12px;align-items:center;padding:12px 15px;border-bottom:2px solid rgba(192,202,245,.08);transition-duration:.2s;transition-timing-function:ease;transition-property:background}.activity-log .activity-log-row:last-child{border-bottom:0}@media(hover:hover)and (pointer:fine){.activity-log .activity-log-row:hover{background:#c0caf516}}@media(hover:none)and (pointer:coarse){.activity-log .activity-log-row:active{background:#c0caf516}}.activity-log .activity-log-time{color:#787c99;font-family:IBM Plex Mono,monospace;font-size:12px}.activity-log .activity-log-title{color:#c0caf5;font-size:13px;font-weight:600;line-height:1.4}@media(max-width:479px){.activity-log .activity-log-row{grid-template-columns:1fr;gap:8px}}.accordion{display:grid;width:100%;max-width:760px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#c0caf50b}.accordion-item{border-bottom:2px solid rgba(192,202,245,.08);overflow:hidden}.accordion-item:last-child{border-bottom:0}.accordion-item[open] .accordion-summary{color:#16161e;background:#c0caf5}.accordion-item[open] .accordion-icon{transform:rotate(180deg)}.accordion-summary{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:46px;padding:12px 15px;color:#c0caf5;cursor:pointer;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background}.accordion-summary::-webkit-details-marker{display:none}.accordion-summary::marker{content:""}.accordion-summary:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.accordion-summary:hover{color:#16161e;background:#7aa2f7}}@media(hover:none)and (pointer:coarse){.accordion-summary:active{color:#16161e;background:#7aa2f7}}.accordion-summary-content{display:flex;align-items:center;gap:8px;min-width:0}.accordion-icon{flex:0 0 auto;font-size:18px;transition-duration:.2s;transition-property:transform}.accordion-panel{overflow:hidden;padding:15px;color:#a9b1d6;font-size:13px;line-height:1.6;transition-duration:.28s;transition-timing-function:ease;transition-property:height,opacity,transform}.accordion-panel p{margin-top:0}.accordion-panel p:last-child{margin-bottom:0}.disclosure{max-width:520px;border:2px solid rgba(192,202,245,.24);background:#c0caf50b}.disclosure .accordion-summary{min-height:38px;padding:8px 12px}.disclosure .accordion-panel{padding:12px}.tabs{display:grid;gap:15px;width:100%;max-width:900px}.tabs-list{display:flex;align-items:stretch;gap:0;max-width:100%;overflow-x:auto;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#c0caf50b;scrollbar-width:thin}.tab{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:46px;padding:12px 15px;border:0;border-right:2px solid rgba(192,202,245,.08);border-radius:0;color:#a9b1d6;background:transparent;font-family:IBM Plex Mono,monospace;font-size:13px;font-weight:700;line-height:1;text-transform:uppercase;white-space:nowrap;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,opacity}.tab .ph,.tab .ph-bold{font-size:18px}.tab:focus-visible{outline:2px solid #E0AF68;outline-offset:3px;z-index:1}@media(hover:hover)and (pointer:fine){.tab:hover{color:#16161e;background:#7aa2f7}}@media(hover:none)and (pointer:coarse){.tab:active{color:#16161e;background:#7aa2f7}}.tab:disabled,.tab[aria-disabled=true]{color:#787c99;cursor:not-allowed;opacity:.62}@media(hover:hover)and (pointer:fine){.tab:disabled:hover,.tab[aria-disabled=true]:hover{color:#787c99;background:transparent}}@media(hover:none)and (pointer:coarse){.tab:disabled:active,.tab[aria-disabled=true]:active{color:#787c99;background:transparent}}.tab-active,.tab[aria-selected=true]{color:#16161e;background:#c0caf5}.tabs-panels{border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#c0caf50b}.tab-panel{display:none;padding:15px;color:#a9b1d6;font-size:13px;line-height:1.6}.tab-panel p{margin-top:0}.tab-panel p:last-child{margin-bottom:0}.tab-panel-active{display:block}.tabs-compact{max-width:620px}.tabs-compact .tabs-list{border-left-width:2px}.tabs-compact .tab{min-height:38px;padding:8px 12px}.tabs-compact .tabs-panels{border-left-width:2px}.tabs-compact .tab-panel{padding:12px}.tabs-vertical{grid-template-columns:minmax(180px,240px) minmax(0,1fr);align-items:start}.tabs-vertical .tabs-list{flex-direction:column;overflow-x:visible}.tabs-vertical .tab{justify-content:flex-start;border-right:0;border-bottom:2px solid rgba(192,202,245,.08);text-align:left}@media(max-width:767px){.tabs-vertical{grid-template-columns:1fr}.tabs-vertical .tabs-list{flex-direction:row;overflow-x:auto}.tabs-vertical .tab{justify-content:center;border-right:2px solid rgba(192,202,245,.08);border-bottom:0;text-align:center}}.drawer{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1000;display:flex;justify-content:flex-end;pointer-events:none}.drawer .drawer-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1010;background:#16161e;opacity:0;transition-duration:.28s;transition-timing-function:ease;transition-property:opacity;pointer-events:auto}.drawer .drawer-panel{position:relative;z-index:1020;width:min(460px,100vw - 18px);min-height:100vh;display:flex;flex-direction:column;gap:15px;background:#16161e;border-left:2px solid #C0CAF5;box-shadow:-18px 0 42px #16161e61;opacity:0;transform:translate(100%);transition-duration:.28s;transition-timing-function:ease;transition-property:opacity,transform;pointer-events:auto}.drawer .drawer-header{display:flex;align-items:center;justify-content:space-between;padding-right:15px;border-bottom:2px solid rgba(192,202,245,.24)}.drawer .drawer-title{margin:0;padding:12px 15px;background:#c0caf5;color:#16161e;text-transform:uppercase;letter-spacing:.04em}.drawer .drawer-body{flex:1;overflow-y:auto;padding:18px}.drawer .drawer-footer{padding:18px;border-top:2px solid rgba(192,202,245,.24)}.drawer .drawer-footer .actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:12px;width:100%}.drawer.drawer-left{justify-content:flex-start}.drawer.drawer-left .drawer-panel{border-left:0;border-right:2px solid #C0CAF5;box-shadow:18px 0 42px #16161e61;transform:translate(-100%)}.drawer.a-show .drawer-backdrop{opacity:.82}.drawer.a-show .drawer-panel{opacity:1;transform:translate(0)}.drawer.a-hide .drawer-backdrop{opacity:0}.drawer.a-hide .drawer-panel{opacity:0;transform:translate(100%)}.drawer.a-hide.drawer-left .drawer-panel{transform:translate(-100%)}.drawer-preview{display:grid;grid-template-columns:minmax(0,1fr) minmax(180px,280px);gap:18px;align-items:stretch;padding:18px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#c0caf50b}.drawer-preview .drawer-preview-content{display:flex;flex-direction:column;gap:12px}.drawer-preview .drawer-preview-panel{display:flex;flex-direction:column;gap:12px;padding:15px;border:2px solid #7AA2F7;background:#1f2335}.drawer-preview .drawer-preview-title{margin:0;color:#7aa2f7;font-size:14px;text-transform:uppercase}.drawer-preview .drawer-preview-text{margin:0;color:#a9b1d6;font-size:13px;line-height:1.6}@media(max-width:720px){.drawer-preview{grid-template-columns:1fr}}.nav-topbar{position:sticky;top:0;z-index:900;display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;min-height:58px;border-bottom:2px solid rgba(192,202,245,.24);background:#16161ef5;box-shadow:0 10px 28px #16161e42}.nav-topbar-toggle{display:inline-flex;align-items:center;align-self:stretch;gap:8px;min-width:150px;padding:0 15px;border:0;border-right:2px solid rgba(192,202,245,.24);color:#c0caf5;background:#1f2335;font-family:IBM Plex Mono,monospace;font-size:13px;font-weight:700;text-transform:uppercase;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background}.nav-topbar-toggle .ph{color:#7aa2f7;font-size:22px}.nav-topbar-toggle:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.nav-topbar-toggle:hover{color:#16161e;background:#7aa2f7}.nav-topbar-toggle:hover .ph{color:#16161e}}@media(hover:none)and (pointer:coarse){.nav-topbar-toggle:active{color:#16161e;background:#7aa2f7}.nav-topbar-toggle:active .ph{color:#16161e}}.nav-topbar-brand{display:inline-flex;align-items:center;gap:8px;min-width:0;padding:0 15px;color:#c0caf5;font-size:13px;font-weight:700;text-transform:uppercase}.nav-topbar-brand img{width:22px;height:22px}.nav-topbar-current{min-width:160px;margin-right:15px;padding:5px 8px;border:2px solid rgba(192,202,245,.24);color:#a9b1d6;background:#c0caf50b;font-size:12px;font-weight:700;text-align:center;text-transform:uppercase}.nav-drawer-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:910;background:#16161e;opacity:0;pointer-events:none;transition-duration:.28s;transition-timing-function:ease;transition-property:opacity}.nav-drawer{position:fixed;inset:0 auto 0 0;z-index:920;display:flex;flex-direction:column;width:min(380px,100vw);max-height:100vh;border-right:2px solid #C0CAF5;background:#1f2335;box-shadow:18px 0 42px #16161e61;opacity:0;overflow:hidden;pointer-events:none;transform:translate(-100%);transition-duration:.28s;transition-timing-function:ease;transition-property:opacity,transform}.nav-drawer.is-open{opacity:1;pointer-events:auto;transform:translate(0)}.nav-drawer-header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px;border-bottom:2px solid rgba(192,202,245,.24)}.nav-drawer-title{display:inline-flex;padding:8px 12px;color:#16161e;background:#c0caf5;font-size:13px;font-weight:700;text-transform:uppercase}.nav-drawer-subtitle{margin-top:8px;color:#787c99;font-size:12px;font-weight:700;text-transform:uppercase}.nav-drawer-close{display:inline-flex;align-items:center;justify-content:center;width:46px;height:46px;padding:0;border:2px solid rgba(192,202,245,.24);color:#c0caf5;background:transparent;font-size:22px;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color}.nav-drawer-close:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.nav-drawer-close:hover{color:#16161e;background:#f7768e;border-color:#f7768e}}@media(hover:none)and (pointer:coarse){.nav-drawer-close:active{color:#16161e;background:#f7768e;border-color:#f7768e}}.nav-drawer-body{flex:1;overflow-y:auto;overscroll-behavior:contain;padding:12px;scrollbar-width:thin;scrollbar-color:#7AA2F7 #1F2335}.nav-drawer-body::-webkit-scrollbar{width:8px}.nav-drawer-body::-webkit-scrollbar-track{background:#1f2335}.nav-drawer-body::-webkit-scrollbar-thumb{background:#7aa2f7}.nav-drawer-body .list.list-nav{max-width:none}.nav-drawer-footer{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px;border-top:2px solid rgba(192,202,245,.24);color:#787c99;background:#c0caf50b;font-size:12px;font-weight:700;text-transform:uppercase}.nav-drawer-open{overflow:hidden}.nav-drawer-open .nav-drawer-backdrop{opacity:.82;pointer-events:auto}@media(max-width:767px){.nav-topbar-toggle{min-width:54px;padding:0 12px}.nav-topbar-brand{padding-right:12px;padding-left:12px}.nav-topbar-current{max-width:38vw;min-width:0;margin-right:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nav-drawer{width:100vw;border-right:0}}.nav-shell-preview{width:100%;max-width:900px;overflow:hidden;border:2px solid rgba(192,202,245,.24);border-left-width:6px;background:#16161e}.nav-shell-preview-topbar{position:relative;z-index:0;min-height:52px;box-shadow:none}.nav-shell-preview-body{display:grid;grid-template-columns:280px minmax(0,1fr);min-height:320px}.nav-shell-preview-drawer{position:relative;z-index:0;inset:auto;width:auto;max-height:none;opacity:1;pointer-events:auto;transform:none;box-shadow:none}.nav-shell-preview-content{display:flex;flex-direction:column;justify-content:center;gap:12px;min-width:0;padding:18px;border-left:2px solid rgba(192,202,245,.24);background:#c0caf50b}.nav-shell-preview-content h3{margin:0;color:#c0caf5;font-size:20px;text-transform:uppercase}.nav-shell-preview-content p{max-width:360px;margin:0;color:#a9b1d6;font-size:13px;line-height:1.6}@media(max-width:767px){.nav-shell-preview-body{grid-template-columns:1fr}.nav-shell-preview-content{min-height:180px;border-top:2px solid rgba(192,202,245,.24);border-left:0}}.toast{position:fixed;z-index:1100;bottom:-100px;right:15px;max-width:420px;background:#1f2335;border:2px solid #C0CAF5;border-left-width:6px;padding:0;opacity:0;transition-duration:.28s;transition-timing-function:ease;transition-property:opacity,top,bottom}.toast.a-show{bottom:15px;opacity:1}.toast.a-hide{bottom:115px;opacity:0}.toast .toast-content{display:flex;flex-direction:column;gap:0}.toast .toast-content .toast-title{min-height:38px;font-size:16px;display:flex;flex-direction:row;gap:8px;align-items:center;color:#16161e;background:#c0caf5;padding:8px 42px 8px 12px;text-transform:uppercase}.toast .toast-content .toast-text{font-size:13px;padding:22px 15px;margin:0}.toast .toast-close{position:absolute;top:0;right:0;color:#16161e;height:38px;width:38px;border-color:transparent}@media(hover:hover)and (pointer:fine){.toast .toast-close:hover{color:#16161e;background:#16161e1f;border-color:#16161e6b}}@media(hover:none)and (pointer:coarse){.toast .toast-close:active{color:#16161e;background:#16161e1f;border-color:#16161e6b}}.toast.toast-info{border-color:#bb9af7}.toast.toast-info .toast-title{background:#bb9af7}.toast.toast-success{border-color:#9ece6a}.toast.toast-success .toast-title{background:#9ece6a}.toast.toast-warning{border-color:#e0af68}.toast.toast-warning .toast-title{background:#e0af68}.toast.toast-danger{border-color:#f7768e}.toast.toast-danger .toast-title{background:#f7768e}.card{position:relative;max-width:340px;width:100%;overflow:hidden;background:#c0caf50b;border:2px solid #C0CAF5;transition-duration:.2s;transition-timing-function:ease;transition-property:border-color,background,box-shadow,transform}.card .card-title{color:#16161e;background:#c0caf5;padding:8px 12px;font-weight:700;text-transform:uppercase}.card .card-content{padding:15px;height:100%}.card .card-content .card-thumb{display:block;width:min(68%,190px);margin:18px auto 22px;transition-duration:.2s;transition-timing-function:ease;transition-property:transform,filter}.card .card-content p{margin-top:8px;margin-bottom:0}.card .card-footer{padding:8px 15px 15px}@media(hover:hover)and (pointer:fine){.card:hover{border-color:#7aa2f7;background:#c0caf516;box-shadow:0 14px 32px #16161e57;transform:translateY(-2px)}.card:hover .card-thumb{filter:saturate(1.12);transform:translateY(-2px)}}@media(hover:none)and (pointer:coarse){.card:active{border-color:#7aa2f7;background:#c0caf516;box-shadow:0 14px 32px #16161e57;transform:translateY(-2px)}.card:active .card-thumb{filter:saturate(1.12);transform:translateY(-2px)}}.card.status-card{max-width:220px;overflow:hidden;transition-duration:.2s;transition-property:border-color}.card.status-card .status-icon-container{position:relative}.card.status-card .status-icon-container .status-indicator{position:absolute;top:-15px;left:-5px;font-size:22px;color:#f7768e}.card.status-card .status-icon-container .status-indicator.status-online{color:#9ece6a}.card.status-card .status-icon-container .status-icon{display:flex;flex-direction:row;align-items:center;justify-content:center;font-size:56px;height:108px;width:100%;transition-duration:.2s;transition-property:color,transform}.card.status-card .card-title{display:flex;width:100%;font-size:14px;font-weight:700;align-items:center;flex-direction:row;flex-wrap:nowrap;justify-content:space-between;transition-duration:.2s;transition-property:background-color,color}.card.status-card .status-name{font-size:13px;line-height:1.4}@media(hover:hover)and (pointer:fine){.card.status-card:hover .status-icon{transform:translateY(-2px) scale(1.03)}}@media(hover:none)and (pointer:coarse){.card.status-card:active .status-icon{transform:translateY(-2px) scale(1.03)}}.card.status-card.card-success{border-color:#9ece6a}.card.status-card.card-success .card-title,.card.status-card.card-success .toast-title,.card.status-card.card-success .modal-title{color:#16161e;background:#9ece6a}.card.status-card.card-success .status-icon{color:#9ece6a}.card.status-card.card-warning{border-color:#e0af68}.card.status-card.card-warning .card-title,.card.status-card.card-warning .toast-title,.card.status-card.card-warning .modal-title{color:#16161e;background:#e0af68}.card.status-card.card-warning .status-icon{color:#e0af68}.card.status-card.card-info{border-color:#bb9af7}.card.status-card.card-info .card-title,.card.status-card.card-info .toast-title,.card.status-card.card-info .modal-title{color:#16161e;background:#bb9af7}.card.status-card.card-info .status-icon{color:#bb9af7}.card.status-card.card-secondary{border-color:#7aa2f7}.card.status-card.card-secondary .card-title,.card.status-card.card-secondary .toast-title,.card.status-card.card-secondary .modal-title{color:#16161e;background:#7aa2f7}.card.status-card.card-secondary .status-icon{color:#7aa2f7}.card.status-card.card-danger,.card.status-card.card-error{border-color:#f7768e}.card.status-card.card-danger .card-title,.card.status-card.card-danger .toast-title,.card.status-card.card-danger .modal-title,.card.status-card.card-error .card-title,.card.status-card.card-error .toast-title,.card.status-card.card-error .modal-title{color:#16161e;background:#f7768e}.card.status-card.card-danger .status-icon,.card.status-card.card-error .status-icon{color:#f7768e}.card.metric-card{max-width:320px;border-color:#c0caf53d}.card.metric-card .card-content{display:flex;flex-direction:column;gap:15px}.card.metric-card .metric-card-header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.card.metric-card .metric-card-label{margin:0;color:#a9b1d6;font-size:13px;font-weight:600;text-transform:uppercase}.card.metric-card .metric-card-icon{display:inline-flex;align-items:center;justify-content:center;width:46px;height:46px;color:#16161e;background:#7aa2f7;font-size:22px;transition-duration:.2s;transition-timing-function:ease;transition-property:background,transform}.card.metric-card .metric-card-value{margin:0;color:#c0caf5;font-size:34px;font-weight:700;line-height:1.15}.card.metric-card .metric-card-meta{display:flex;flex-wrap:wrap;align-items:center;gap:8px;color:#787c99;font-size:13px}.card.metric-card .metric-card-delta{color:#9ece6a;font-weight:700}.card.metric-card .metric-card-delta.metric-card-delta-negative{color:#f7768e}@media(hover:hover)and (pointer:fine){.card.metric-card:hover .metric-card-icon{background:#c0caf5;transform:translateY(-2px)}}@media(hover:none)and (pointer:coarse){.card.metric-card:active .metric-card-icon{background:#c0caf5;transform:translateY(-2px)}}.card.action-card{max-width:360px;border-color:#7aa2f7}.card.action-card .card-content{display:flex;flex-direction:column;gap:15px}.card.action-card .action-card-kicker{display:inline-flex;width:max-content;padding:5px 8px;color:#16161e;background:#7aa2f7;font-size:12px;font-weight:700;line-height:1;text-transform:uppercase;transition-duration:.2s;transition-timing-function:ease;transition-property:background,transform}.card.action-card .action-card-title{margin:0;font-size:20px;font-weight:700;line-height:1.25;text-transform:uppercase}.card.action-card .action-card-text{margin:0;color:#a9b1d6;font-size:13px;line-height:1.6}.card.action-card .action-card-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}@media(hover:hover)and (pointer:fine){.card.action-card:hover .action-card-kicker{background:#c0caf5;transform:translate(5px)}}@media(hover:none)and (pointer:coarse){.card.action-card:active .action-card-kicker{background:#c0caf5;transform:translate(5px)}}.modal{position:fixed;top:0;bottom:0;left:0;right:0;z-index:1000;display:flex;flex-direction:column;align-items:center;justify-content:center}.modal .modal-backdrop{position:fixed;z-index:1010;top:0;bottom:0;left:0;right:0;background:#16161e;opacity:0;transition-duration:.25s;transition-property:opacity}.modal .modal-dialog{position:relative;z-index:1020;width:100%;max-width:960px;margin:200px 18px 18px;height:auto;max-height:calc(100vh - 48px);padding:0;display:flex;flex-direction:column;gap:0;opacity:0;transition-duration:.28s;transition-timing-function:ease;transition-property:opacity,margin-top}.modal .modal-dialog .modal-header{display:flex;flex-direction:row;justify-content:space-between;align-items:center;gap:15px}.modal .modal-dialog .modal-header .modal-title{padding:12px 15px;background:#c0caf5;color:#16161e;text-transform:uppercase;letter-spacing:.04em}.modal .modal-dialog .modal-header .modal-close{flex:0 0 auto;color:#c0caf5;border-color:#c0caf53d;background:#16161e}.modal .modal-dialog .modal-panel{min-height:200px;display:flex;flex-direction:column;gap:15px;overflow:hidden;background:#16161e;border:2px solid #C0CAF5;border-left-width:6px}.modal .modal-dialog .modal-body{max-height:700px;overflow-y:auto;padding:18px}.modal .modal-dialog .modal-footer{padding:18px}.modal .modal-dialog .modal-footer .actions{display:flex;flex-direction:row;justify-content:flex-end;gap:15px;width:100%}.modal.a-show .modal-backdrop{opacity:1}.modal.a-show .modal-dialog{opacity:1;margin-top:0}.modal.a-hide .modal-backdrop{opacity:0}.modal.a-hide .modal-dialog{opacity:0;margin-top:-200px}.alert{position:relative;overflow:hidden;margin-bottom:12px;padding:12px 15px;border:2px solid transparent;border-left-style:solid;border-left-width:6px;background:#c0caf50b;color:#c0caf5;font-weight:500;line-height:1.4;transition-duration:.2s;transition-timing-function:ease;transition-property:background,color,border-color}.alert:after{content:"";position:absolute;inset:0 auto 0 0;width:36%;background:linear-gradient(90deg,transparent,rgba(192,202,245,.12),transparent);opacity:0;pointer-events:none;transform:translate(-120%)}@media(hover:hover)and (pointer:fine){.alert:hover:after{opacity:1;animation:terminal_scan_x .8s ease}}@media(hover:none)and (pointer:coarse){.alert:active:after{opacity:1;animation:terminal_scan_x .8s ease}}.alert.alert-primary{border-color:#c0caf5;background:#c0caf51a;color:#c0caf5}.alert.alert-success{border-color:#9ece6a;background:#9ece6a1a;color:#9ece6a}.alert.alert-secondary{border-color:#7aa2f7;background:#7aa2f71a;color:#7aa2f7}.alert.alert-info{border-color:#bb9af7;background:#bb9af71a;color:#c0caf5}.alert.alert-warning{border-color:#e0af68;background:#e0af681a;color:#e0af68}.alert.alert-error,.alert.alert-danger{border-color:#f7768e;background:#f7768e1a;color:#f7768e}.advanced-select-container{position:relative;height:0}.advanced-select{position:absolute;z-index:100;top:6px;width:100%;height:auto;max-height:200px;overflow-y:auto;background:#16161e;border:2px solid #C0CAF5;border-left-width:6px;margin-top:20px;opacity:0;visibility:hidden;transition-property:opacity,margin-top,visibility;transition-duration:.2s;transition-timing-function:ease}.advanced-select.a-show{opacity:1;margin-top:0;visibility:visible}.advanced-select .popup-options-container .not-found{width:100%;padding:15px;text-align:center;display:none}.advanced-select .popup-options-container .not-found.show{display:block}.advanced-select .popup-options-container .options{width:100%;display:none}.advanced-select .popup-options-container .options.show{display:block}.advanced-select .popup-options-container .options .option{padding:8px 15px;transition-property:color,background;transition-duration:.15s}.advanced-select .popup-options-container .options .option.hide{display:none}.advanced-select .popup-options-container .options .option:hover,.advanced-select .popup-options-container .options .option.focus{color:#16161e;background:#e0af68}.component.editable-string-component .editable-string-content{display:flex;flex-direction:row;align-items:center;gap:8px;font-size:inherit}.component.editable-string-component .editable-string-content .editable-string{font-size:inherit;border-bottom:2px solid rgba(192,202,245,.24)}@media(hover:hover)and (pointer:fine){.component.editable-string-component .edit-text-btn:hover,.component.editable-string-component .apply-changes-btn:hover,.component.editable-string-component .cancel-changes-btn:hover{color:#16161e;background:#e0af68}}@media(hover:none)and (pointer:coarse){.component.editable-string-component .edit-text-btn:active,.component.editable-string-component .apply-changes-btn:active,.component.editable-string-component .cancel-changes-btn:active{color:#16161e;background:#e0af68}}.component.editable-string-component .apply-changes-btn{color:#e0af68}.component.editable-string-component .editable-string-form{display:flex;flex-direction:row;align-items:center;gap:8px}.component.editable-string-component .editable-string-form .form-group{max-width:260px;margin:0}.component.editable-string-component .editable-string-form .form-group .input{padding:8px 15px}.tabs{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:15px}.tabs .tab{display:inline-flex;align-items:center;min-height:38px;padding:8px 12px;border:2px solid rgba(192,202,245,.24);border-left-width:6px;color:#a9b1d6;background:#c0caf50b;font-family:IBM Plex Mono,monospace;font-size:13px;font-weight:600;line-height:1;text-transform:uppercase;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background,border-color}.tabs .tab:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.tabs .tab:hover{color:#16161e;background:#7aa2f7;border-color:#7aa2f7}}@media(hover:none)and (pointer:coarse){.tabs .tab:active{color:#16161e;background:#7aa2f7;border-color:#7aa2f7}}.tabs .tab.tab-active,.tabs .tab[aria-selected=true]{color:#16161e;background:#c0caf5;border-color:#c0caf5}.dropdown,.popover{position:relative;display:inline-flex}.dropdown-menu,.popover-panel,.tooltip-panel{z-index:40;background:#1f2335;border:2px solid rgba(192,202,245,.24);border-left-width:6px;box-shadow:0 14px 36px #16161e5c}.dropdown-menu,.popover-panel{position:absolute;top:calc(100% + 8px);left:0;min-width:220px;display:none;transform-origin:top left}.dropdown.is-open .dropdown-menu,.popover.is-open .popover-panel{display:block;animation:overlay_reveal .2s ease both}.dropdown-menu{padding:5px}.dropdown-menu .dropdown-item{display:flex;align-items:center;gap:8px;width:100%;min-height:38px;padding:8px 12px;border:0;color:#c0caf5;background:transparent;font-family:IBM Plex Mono,monospace;font-size:13px;text-align:left;cursor:pointer;transition-duration:.2s;transition-timing-function:ease;transition-property:color,background}.dropdown-menu .dropdown-item .ph,.dropdown-menu .dropdown-item .ph-bold{font-size:18px}.dropdown-menu .dropdown-item:focus-visible{outline:2px solid #E0AF68;outline-offset:3px}@media(hover:hover)and (pointer:fine){.dropdown-menu .dropdown-item:hover{color:#16161e;background:#7aa2f7}}@media(hover:none)and (pointer:coarse){.dropdown-menu .dropdown-item:active{color:#16161e;background:#7aa2f7}}.dropdown-menu .dropdown-item.dropdown-item-danger{color:#f7768e}@media(hover:hover)and (pointer:fine){.dropdown-menu .dropdown-item.dropdown-item-danger:hover{color:#16161e;background:#f7768e}}@media(hover:none)and (pointer:coarse){.dropdown-menu .dropdown-item.dropdown-item-danger:active{color:#16161e;background:#f7768e}}.popover-panel{width:min(320px,100vw - 22px);padding:15px}.popover-panel .popover-title{margin:0 0 8px;font-size:14px;font-weight:700;text-transform:uppercase}.popover-panel .popover-text{margin:0;color:#a9b1d6;font-size:13px;line-height:1.6}.tooltip{position:relative;display:inline-flex}.tooltip-panel{position:absolute;left:50%;bottom:calc(100% + 8px);width:max-content;max-width:260px;padding:8px 12px;color:#c0caf5;font-size:12px;line-height:1.4;transform:translate(-50%);opacity:0;visibility:hidden;pointer-events:none;transition-duration:.15s;transition-timing-function:ease;transition-property:opacity,visibility}.tooltip:hover .tooltip-panel,.tooltip:focus-within .tooltip-panel,.tooltip.is-open .tooltip-panel{opacity:1;visibility:visible;animation:tooltip_reveal .15s ease both}.m-0{margin:0!important}.mt-0{margin-top:0!important}.mr-0{margin-right:0!important}.mb-0{margin-bottom:0!important}.ml-0{margin-left:0!important}.mx-0{margin-left:0!important;margin-right:0!important}.my-0{margin-top:0!important;margin-bottom:0!important}.p-0{padding:0!important}.pt-0{padding-top:0!important}.pr-0{padding-right:0!important}.pb-0{padding-bottom:0!important}.pl-0{padding-left:0!important}.px-0{padding-left:0!important;padding-right:0!important}.py-0{padding-top:0!important;padding-bottom:0!important}.g-0{gap:0!important}.gx-0{column-gap:0!important}.gy-0{row-gap:0!important}.m-1{margin:5px!important}.mt-1{margin-top:5px!important}.mr-1{margin-right:5px!important}.mb-1{margin-bottom:5px!important}.ml-1{margin-left:5px!important}.mx-1{margin-left:5px!important;margin-right:5px!important}.my-1{margin-top:5px!important;margin-bottom:5px!important}.p-1{padding:5px!important}.pt-1{padding-top:5px!important}.pr-1{padding-right:5px!important}.pb-1{padding-bottom:5px!important}.pl-1{padding-left:5px!important}.px-1{padding-left:5px!important;padding-right:5px!important}.py-1{padding-top:5px!important;padding-bottom:5px!important}.g-1{gap:5px!important}.gx-1{column-gap:5px!important}.gy-1{row-gap:5px!important}.m-2{margin:8px!important}.mt-2{margin-top:8px!important}.mr-2{margin-right:8px!important}.mb-2{margin-bottom:8px!important}.ml-2{margin-left:8px!important}.mx-2{margin-left:8px!important;margin-right:8px!important}.my-2{margin-top:8px!important;margin-bottom:8px!important}.p-2{padding:8px!important}.pt-2{padding-top:8px!important}.pr-2{padding-right:8px!important}.pb-2{padding-bottom:8px!important}.pl-2{padding-left:8px!important}.px-2{padding-left:8px!important;padding-right:8px!important}.py-2{padding-top:8px!important;padding-bottom:8px!important}.g-2{gap:8px!important}.gx-2{column-gap:8px!important}.gy-2{row-gap:8px!important}.m-3{margin:12px!important}.mt-3{margin-top:12px!important}.mr-3{margin-right:12px!important}.mb-3{margin-bottom:12px!important}.ml-3{margin-left:12px!important}.mx-3{margin-left:12px!important;margin-right:12px!important}.my-3{margin-top:12px!important;margin-bottom:12px!important}.p-3{padding:12px!important}.pt-3{padding-top:12px!important}.pr-3{padding-right:12px!important}.pb-3{padding-bottom:12px!important}.pl-3{padding-left:12px!important}.px-3{padding-left:12px!important;padding-right:12px!important}.py-3{padding-top:12px!important;padding-bottom:12px!important}.g-3{gap:12px!important}.gx-3{column-gap:12px!important}.gy-3{row-gap:12px!important}.m-4{margin:15px!important}.mt-4{margin-top:15px!important}.mr-4{margin-right:15px!important}.mb-4{margin-bottom:15px!important}.ml-4{margin-left:15px!important}.mx-4{margin-left:15px!important;margin-right:15px!important}.my-4{margin-top:15px!important;margin-bottom:15px!important}.p-4{padding:15px!important}.pt-4{padding-top:15px!important}.pr-4{padding-right:15px!important}.pb-4{padding-bottom:15px!important}.pl-4{padding-left:15px!important}.px-4{padding-left:15px!important;padding-right:15px!important}.py-4{padding-top:15px!important;padding-bottom:15px!important}.g-4{gap:15px!important}.gx-4{column-gap:15px!important}.gy-4{row-gap:15px!important}.m-5{margin:18px!important}.mt-5{margin-top:18px!important}.mr-5{margin-right:18px!important}.mb-5{margin-bottom:18px!important}.ml-5{margin-left:18px!important}.mx-5{margin-left:18px!important;margin-right:18px!important}.my-5{margin-top:18px!important;margin-bottom:18px!important}.p-5{padding:18px!important}.pt-5{padding-top:18px!important}.pr-5{padding-right:18px!important}.pb-5{padding-bottom:18px!important}.pl-5{padding-left:18px!important}.px-5{padding-left:18px!important;padding-right:18px!important}.py-5{padding-top:18px!important;padding-bottom:18px!important}.g-5{gap:18px!important}.gx-5{column-gap:18px!important}.gy-5{row-gap:18px!important}.m-6{margin:22px!important}.mt-6{margin-top:22px!important}.mr-6{margin-right:22px!important}.mb-6{margin-bottom:22px!important}.ml-6{margin-left:22px!important}.mx-6{margin-left:22px!important;margin-right:22px!important}.my-6{margin-top:22px!important;margin-bottom:22px!important}.p-6{padding:22px!important}.pt-6{padding-top:22px!important}.pr-6{padding-right:22px!important}.pb-6{padding-bottom:22px!important}.pl-6{padding-left:22px!important}.px-6{padding-left:22px!important;padding-right:22px!important}.py-6{padding-top:22px!important;padding-bottom:22px!important}.g-6{gap:22px!important}.gx-6{column-gap:22px!important}.gy-6{row-gap:22px!important}.m-7{margin:26px!important}.mt-7{margin-top:26px!important}.mr-7{margin-right:26px!important}.mb-7{margin-bottom:26px!important}.ml-7{margin-left:26px!important}.mx-7{margin-left:26px!important;margin-right:26px!important}.my-7{margin-top:26px!important;margin-bottom:26px!important}.p-7{padding:26px!important}.pt-7{padding-top:26px!important}.pr-7{padding-right:26px!important}.pb-7{padding-bottom:26px!important}.pl-7{padding-left:26px!important}.px-7{padding-left:26px!important;padding-right:26px!important}.py-7{padding-top:26px!important;padding-bottom:26px!important}.g-7{gap:26px!important}.gx-7{column-gap:26px!important}.gy-7{row-gap:26px!important}.m-8{margin:34px!important}.mt-8{margin-top:34px!important}.mr-8{margin-right:34px!important}.mb-8{margin-bottom:34px!important}.ml-8{margin-left:34px!important}.mx-8{margin-left:34px!important;margin-right:34px!important}.my-8{margin-top:34px!important;margin-bottom:34px!important}.p-8{padding:34px!important}.pt-8{padding-top:34px!important}.pr-8{padding-right:34px!important}.pb-8{padding-bottom:34px!important}.pl-8{padding-left:34px!important}.px-8{padding-left:34px!important;padding-right:34px!important}.py-8{padding-top:34px!important;padding-bottom:34px!important}.g-8{gap:34px!important}.gx-8{column-gap:34px!important}.gy-8{row-gap:34px!important}.m-9{margin:42px!important}.mt-9{margin-top:42px!important}.mr-9{margin-right:42px!important}.mb-9{margin-bottom:42px!important}.ml-9{margin-left:42px!important}.mx-9{margin-left:42px!important;margin-right:42px!important}.my-9{margin-top:42px!important;margin-bottom:42px!important}.p-9{padding:42px!important}.pt-9{padding-top:42px!important}.pr-9{padding-right:42px!important}.pb-9{padding-bottom:42px!important}.pl-9{padding-left:42px!important}.px-9{padding-left:42px!important;padding-right:42px!important}.py-9{padding-top:42px!important;padding-bottom:42px!important}.g-9{gap:42px!important}.gx-9{column-gap:42px!important}.gy-9{row-gap:42px!important}.m-10{margin:48px!important}.mt-10{margin-top:48px!important}.mr-10{margin-right:48px!important}.mb-10{margin-bottom:48px!important}.ml-10{margin-left:48px!important}.mx-10{margin-left:48px!important;margin-right:48px!important}.my-10{margin-top:48px!important;margin-bottom:48px!important}.p-10{padding:48px!important}.pt-10{padding-top:48px!important}.pr-10{padding-right:48px!important}.pb-10{padding-bottom:48px!important}.pl-10{padding-left:48px!important}.px-10{padding-left:48px!important;padding-right:48px!important}.py-10{padding-top:48px!important;padding-bottom:48px!important}.g-10{gap:48px!important}.gx-10{column-gap:48px!important}.gy-10{row-gap:48px!important}.m-11{margin:64px!important}.mt-11{margin-top:64px!important}.mr-11{margin-right:64px!important}.mb-11{margin-bottom:64px!important}.ml-11{margin-left:64px!important}.mx-11{margin-left:64px!important;margin-right:64px!important}.my-11{margin-top:64px!important;margin-bottom:64px!important}.p-11{padding:64px!important}.pt-11{padding-top:64px!important}.pr-11{padding-right:64px!important}.pb-11{padding-bottom:64px!important}.pl-11{padding-left:64px!important}.px-11{padding-left:64px!important;padding-right:64px!important}.py-11{padding-top:64px!important;padding-bottom:64px!important}.g-11{gap:64px!important}.gx-11{column-gap:64px!important}.gy-11{row-gap:64px!important}.m-12{margin:80px!important}.mt-12{margin-top:80px!important}.mr-12{margin-right:80px!important}.mb-12{margin-bottom:80px!important}.ml-12{margin-left:80px!important}.mx-12{margin-left:80px!important;margin-right:80px!important}.my-12{margin-top:80px!important;margin-bottom:80px!important}.p-12{padding:80px!important}.pt-12{padding-top:80px!important}.pr-12{padding-right:80px!important}.pb-12{padding-bottom:80px!important}.pl-12{padding-left:80px!important}.px-12{padding-left:80px!important;padding-right:80px!important}.py-12{padding-top:80px!important;padding-bottom:80px!important}.g-12{gap:80px!important}.gx-12{column-gap:80px!important}.gy-12{row-gap:80px!important}.row{display:flex;flex-direction:row}@media(max-width:1279px){.row.adaptive{flex-direction:column}}.column{display:flex;flex-direction:column}.f-grid{display:flex;flex-direction:row;flex-wrap:wrap}.grid{display:grid}.grid-2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}.grid-3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}.items-start{align-items:flex-start!important}.items-center{align-items:center!important}.items-end{align-items:flex-end!important}.justify-start{justify-content:flex-start!important}.justify-center{justify-content:center!important}.justify-between{justify-content:space-between!important}.justify-end{justify-content:flex-end!important}.w-100{width:100%}.w-auto{width:auto!important}.w-fit{width:fit-content!important}.w-200{width:200%}.h-100{height:100%}.min-w-0{min-width:0!important}.overflow-hidden{overflow:hidden!important}.overflow-auto{overflow:auto!important}.fs-xs{font-size:12px}.fs-sm{font-size:13px}.fs-md{font-size:14px}.fs-base{font-size:15px}.fs-lg{font-size:16px}.fs-xl{font-size:20px}.text-left{text-align:left!important}.text-center{text-align:center!important}.text-right{text-align:right!important}.text-uppercase{text-transform:uppercase!important}.text-nowrap{white-space:nowrap!important}.d-none{display:none!important}.d-block{display:block!important}.d-inline-flex{display:inline-flex!important}.d-flex{display:flex!important}.d-grid{display:grid!important}@media(max-width:767px){.grid-2,.grid-3{grid-template-columns:1fr}}*{box-sizing:border-box}html,body{padding:0;margin:0}body{background-color:#16161e;color:#c0caf5}*::-webkit-scrollbar-corner{background:transparent;height:1px}.ph.normalize{position:relative;top:.15em}html,body{height:100%}*::-webkit-scrollbar{width:10px}*::-webkit-scrollbar-track{width:10px;background:#16161e;cursor:pointer}*::-webkit-scrollbar-thumb{width:10px;background:#414868;cursor:default}*::-webkit-scrollbar-corner{background:transparent}*::-webkit-scrollbar-button{display:none}#app{display:flex;height:100vh;height:100dvh;overflow:hidden}.app-main{flex:1 1 0;min-width:0;min-height:0;display:flex;flex-direction:column;overflow:hidden;background:#16161e}.app-sidebar{width:380px;min-width:380px;max-width:380px;display:flex;flex-direction:column;background:#1f2335;border-right:2px solid rgba(192,202,245,.24);overflow:hidden;flex-shrink:0;transition:width .22s ease,min-width .22s ease,max-width .22s ease,border-color .22s ease,transform .28s ease}.app-sidebar.is-hidden-by-artifacts{width:0;min-width:0;max-width:0;border-right-color:transparent}@media(max-width:1280px){.app-sidebar{position:fixed;top:0;right:0;bottom:0;left:0;z-index:100;width:min(380px,92vw)!important;min-width:min(380px,92vw)!important;transform:translate(-100%);transition:transform .28s ease}.app-sidebar.is-mobile-open{transform:translate(0)}.app-sidebar.is-hidden-by-artifacts{width:min(380px,92vw)!important;min-width:min(380px,92vw)!important;max-width:min(380px,92vw)!important;border-right-color:#c0caf53d}}@media(max-width:980px){.app-sidebar,.app-sidebar.is-hidden-by-artifacts{width:100vw!important;min-width:100vw!important;max-width:100vw!important}}.sidebar-header{padding:15px;border-bottom:2px solid rgba(192,202,245,.24);display:flex;flex-direction:column;gap:8px}.sidebar-controls-row{display:flex;align-items:center;gap:8px}.sidebar-controls-row .sidebar-profile-select{flex:1;min-width:0}.sidebar-logo{display:flex;align-items:center;gap:8px;text-decoration:none}.sidebar-logo img{width:28px;height:28px}.sidebar-logo span{font-size:18px;font-weight:700;color:#c0caf5;letter-spacing:-.3px}.sidebar-sessions{flex:1;overflow:hidden;display:flex;flex-direction:column}.sessions-header{display:flex;align-items:center;justify-content:space-between;padding:8px 15px;gap:8px}.sessions-label{font-size:11px;text-transform:uppercase;letter-spacing:.08em;color:#787c99}.sessions-refresh-btn{font-size:14px;color:#787c99;transition:color .15s,transform .15s}.sessions-refresh-btn:hover{color:#c0caf5}.sessions-refresh-btn.is-spinning i{animation:spin .8s linear infinite}.sidebar-profile-select{position:relative}.sidebar-profile-select select{width:100%;-moz-appearance:none;appearance:none;-webkit-appearance:none;min-height:46px;font-family:inherit;font-size:13px;font-weight:500;padding:5px 34px 5px 15px;border:2px solid rgba(192,202,245,.24);border-bottom-width:6px;border-bottom-color:#c0caf5;color:#c0caf5;background-color:#c0caf50b;cursor:pointer;transition:border-color .2s ease,background-color .2s ease;outline:none}.sidebar-profile-select select:hover{border-bottom-color:#787c99}.sidebar-profile-select select:focus{outline:2px solid #E0AF68;outline-offset:3px;border-color:#7aa2f7;background-color:transparent}.sidebar-profile-select select option{background:#1f2335;color:#c0caf5}.sidebar-profile-select:after{content:"";position:absolute;right:15px;top:50%;transform:translateY(-50%);width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent;border-top:5px solid #A9B1D6;pointer-events:none}.session-item{display:flex;align-items:flex-start;gap:8px;padding:8px 15px;cursor:pointer;border-radius:0;transition:background .15s ease;position:relative}.session-item:hover{background:#c0caf50b}.session-item:hover .session-actions{opacity:1}@media(hover:none){.session-item .session-actions{opacity:1}}.session-item.is-active{background:#c0caf516;border-left:6px solid #7AA2F7;padding-left:9px}.session-item.is-pinned{background:#e0af6812}.session-item.is-pinned .session-name{color:#e0af68}.session-item.has-recall .session-actions{opacity:1}.session-icons{display:flex;flex-direction:column;align-items:center;gap:2px;flex-shrink:0;margin-top:2px;width:14px}.session-icons .session-pin-icon,.session-icons .session-recall-icon{color:#787c99;font-size:14px;opacity:0;transition:opacity .15s ease}.session-icons .session-pin-icon{color:#e0af68}.session-icons .session-recall-icon{color:var(--color-accent, #7aa2f7)}.is-pinned .session-icons .session-pin-icon,.has-recall .session-icons .session-recall-icon{opacity:1}.session-info{flex:1;overflow:hidden}.session-name{font-size:13px;color:#a9b1d6;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.4}.session-time{font-size:11px;color:#787c99;line-height:1.4;margin-top:2px}.session-preview{font-size:12px;color:#c0caf5;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;line-height:1.4;margin-top:3px}.session-actions{display:flex;gap:2px;opacity:0;transition:opacity .15s ease;flex-shrink:0;align-self:flex-start;margin-top:1px}.session-actions .btn-icon{width:26px;height:26px;font-size:14px}.chat-area{flex:1 1 0;min-height:0;min-width:0;display:flex;flex-direction:column;overflow:hidden;background:#16161e}.chat-header{display:flex;align-items:center;gap:8px;padding:8px 15px;border-bottom:2px solid rgba(192,202,245,.24);background:#1f2335;flex-shrink:0;min-height:54px}.chat-header-info{flex:1;display:flex;align-items:center;gap:8px;overflow:hidden;min-width:0}@media(max-width:768px){.chat-header-info{flex-direction:column;align-items:flex-start;gap:2px}}.chat-header-title{font-size:14px;font-weight:600;color:#c0caf5;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex-shrink:1;min-width:0}.profile-badge{display:inline-flex;align-items:center;gap:6px;flex-shrink:0}.profile-badge .profile-badge-name{font-size:12px;color:#787c99;white-space:nowrap}.btn-sidebar-toggle{display:none}@media(max-width:1280px){.btn-sidebar-toggle{display:flex}}.context-bar{display:flex;align-items:center;flex-shrink:0;cursor:default}.profile-badge{display:inline-flex;align-items:center;gap:5px;padding:2px 8px;background:#c0caf50b;border:2px solid rgba(192,202,245,.24);font-size:12px;color:#a9b1d6;white-space:nowrap}.message-list{flex:1;overflow-y:auto;overflow-x:hidden;padding:22px 15px;display:flex;flex-direction:column;gap:15px;min-height:0}@media(max-width:768px){.message-list{padding-left:10px;padding-right:10px}}.message-list .vue-recycle-scroller{flex:1}.message-list-inner{display:flex;flex-direction:column;gap:34px;width:100%;max-width:920px;margin:0 auto;padding:34px 22px;transition:opacity .2s ease}@media(max-width:768px){.message-list-inner{padding-left:0;padding-right:0}}.message-list-inner.is-hidden{opacity:0;pointer-events:none}.msg-user{display:flex;justify-content:flex-end;gap:8px}.msg-user-bubble{background:#7aa2f7;color:#16161e;padding:8px 15px;font-size:14px;line-height:1.6;word-wrap:break-word;width:100%}.msg-user-bubble .msg-user-quote{margin:0 0 5px;padding:2px 0 2px 8px;border-left:3px solid rgba(22,22,30,.35);opacity:.7;font-size:13px}.msg-user--recall .msg-user-bubble{background:#7aa2f71f;border:1px solid rgba(122,162,247,.25)}.msg-user--recall .msg-user-bubble .msg-user-text{color:#c0caf5}.msg-recall-badge{display:inline-flex;align-items:center;gap:4px;font-size:11px;color:#7aa2f7;margin-bottom:4px;opacity:.85}.msg-user-attachments{display:flex;flex-wrap:wrap;gap:5px;margin-top:5px}.msg-user-image{width:80px;height:80px;object-fit:cover;cursor:pointer;transition:opacity .15s}.msg-user-image:hover{opacity:.75}.msg-user-file-pill{display:inline-flex;align-items:center;gap:5px;padding:2px 8px;background:#16161e4d;font-size:12px}.msg-time{font-size:11px;color:#787c99;line-height:1;margin-top:4px}.msg-meta-row{display:flex;align-items:center;gap:8px;margin-top:2px;min-width:0}.msg-meta-item{display:inline-flex;align-items:center;gap:4px;font-size:11px;color:#787c99;white-space:nowrap}.msg-meta-item i{font-size:12px;opacity:.7}.msg-user-wrap{display:flex;flex-direction:column;align-items:flex-end;max-width:70%}@media(max-width:768px){.msg-user-wrap{max-width:90%}}.msg-user-footer{display:flex;align-items:center;gap:5px;align-self:flex-end}.msg-copy-btn{width:22px;height:22px;min-width:22px;padding:0;font-size:12px;opacity:.5;transition:opacity .15s}.msg-copy-btn:hover{opacity:1}.msg-meta-row>.msg-copy-btn{margin-left:auto}.msg-meta-row .msg-rate-btn{width:22px;height:22px;min-width:22px;padding:0;font-size:13px}.msg-assistant{display:flex;flex-direction:column;gap:8px;max-width:100%}.planning-indicator{display:flex;align-items:center;gap:8px;font-size:13px;font-style:italic;color:#787c99;padding:5px 0}.planning-indicator.is-executing{color:#a9b1d6;font-style:normal}.planning-label{opacity:.75;transition:opacity .2s}.msg-assistant-avatar{width:28px;height:28px;border-radius:50%;flex-shrink:0}.msg-assistant-content{font-size:14px;line-height:1.7;color:#c0caf5;display:flex;flex-wrap:wrap;gap:8px}.msg-assistant-content>p,.msg-assistant-content>ul,.msg-assistant-content>ol,.msg-assistant-content>blockquote,.msg-assistant-content>pre,.msg-assistant-content>.table-wrap,.msg-assistant-content>h1,.msg-assistant-content>h2,.msg-assistant-content>h3,.msg-assistant-content>h4,.msg-assistant-content>hr{flex:1 1 100%;margin:0}.msg-assistant-content>p:has(>.msg-md-image-link:only-child){flex:0 0 calc((100% - 16px) / 3)}.msg-assistant-content h1,.msg-assistant-content h2,.msg-assistant-content h3,.msg-assistant-content h4{color:#c0caf5}.msg-assistant-content ul,.msg-assistant-content ol{padding-left:22px}.msg-assistant-content li{margin-bottom:8px}.msg-assistant-content blockquote{padding-left:15px;border-left:6px solid #7AA2F7;color:#a9b1d6}.msg-assistant-content a{color:#7aa2f7}.msg-assistant-content strong{color:#c0caf5}.msg-assistant-content hr{border:none;border-top:1px solid rgba(192,202,245,.24)}.msg-assistant-content .msg-md-image-link{display:block;width:100%;text-decoration:none;border:2px solid rgba(192,202,245,.12);border-radius:4px;overflow:hidden;transition:border-color .2s ease;cursor:zoom-in}.msg-assistant-content .msg-md-image-link:hover{border-color:#7aa2f7}.msg-assistant-content .msg-md-image{display:block;width:100%;aspect-ratio:1/1;object-fit:cover;border-radius:2px}.msg-assistant-content .msg-md-image-link.is-broken{cursor:default;border-color:#f7768e66;background:#f7768e0f;display:flex;align-items:center;justify-content:center;aspect-ratio:1/1}.msg-assistant-content .msg-md-image-link.is-broken:before{content:"🖼️";font-size:32px;opacity:.4}.msg-assistant-content .msg-md-image-link.is-broken:hover{border-color:#f7768e66}.msg-assistant-content .msg-md-image-link.is-broken .msg-md-image{display:none}.msg-assistant-content .table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:15px 0}.msg-assistant-content .table{margin:15px 0}.msg-assistant-content .table thead{border-bottom:2px solid #C0CAF5}.msg-assistant-content .table tbody tr{transition:background .2s ease}.msg-assistant-content .table tbody tr:hover{background:#7aa2f714}.msg-assistant-content .table tbody tr:hover td:first-child{color:#7aa2f7}.msg-assistant-content .table tr th,.msg-assistant-content .table tr td{padding:8px 15px;font-size:13px;vertical-align:middle;border-bottom:2px solid rgba(192,202,245,.08)}.msg-assistant-content .table tr th{color:#c0caf5;background:#c0caf50a;text-transform:uppercase;letter-spacing:.06em}.msg-assistant-content :not(pre)>code{font-family:IBM Plex Mono,monospace;font-size:13px;background:#c0caf516;padding:1px 5px;color:#7dcfff}.msg-assistant-content .code-block{margin:15px 0;background:#1f2335;border:2px solid rgba(192,202,245,.24);overflow:hidden}.msg-assistant-content .code-block .code-header{display:flex;align-items:center;justify-content:space-between;padding:5px 15px;background:#c0caf516;border-bottom:2px solid rgba(192,202,245,.24);font-size:12px;color:#787c99;font-family:IBM Plex Mono,monospace}.msg-assistant-content .code-block pre{margin:0;background:#1f2335!important}.msg-assistant-content .code-block pre code{font-family:IBM Plex Mono,monospace;font-size:13px;display:block;padding:15px;overflow-x:auto}.thinking-card summary{list-style:none;display:flex;align-items:center;gap:8px;padding:5px 15px;cursor:pointer;color:#787c99;font-size:12px;font-style:italic;background:#c0caf50b;border:2px solid rgba(192,202,245,.24);transition:background .15s ease;-webkit-user-select:none;user-select:none}.thinking-card summary::-webkit-details-marker{display:none}.thinking-card summary:hover{background:#c0caf516}.thinking-card[open] summary{border-bottom-color:transparent}.thinking-card .thinking-chevron{margin-left:auto;font-size:18px;color:#787c99;flex-shrink:0;transition:transform .15s ease}.thinking-card[open] .thinking-chevron{transform:rotate(180deg)}.thinking-card .thinking-body{padding:8px 15px;font-size:12px;font-style:italic;color:#a9b1d6;line-height:1.5;background:#c0caf50b;border:2px solid rgba(192,202,245,.24);border-top:none;white-space:pre-wrap;word-break:break-word}.plan-card{border:2px solid #7AA2F7;border-left-width:6px;border-left-color:#7aa2f7;overflow:hidden;font-size:12px;margin-bottom:8px}.plan-card summary{list-style:none;display:flex;align-items:center;gap:8px;padding:5px 15px;cursor:pointer;background:#7aa2f714;color:#7aa2f7;font-size:12px;-webkit-user-select:none;user-select:none}.plan-card summary::-webkit-details-marker{display:none}.plan-card summary:hover{background:#7aa2f724}.plan-card summary .plan-chevron{margin-left:auto;font-size:18px;color:#7aa2f799;transition:transform .15s ease;flex-shrink:0}.plan-card[open] .plan-chevron{transform:rotate(180deg)}.plan-card .plan-body{padding:8px 15px;font-size:12px;color:#a9b1d6;line-height:1.5;background:#7aa2f70a;border-top:2px solid rgba(122,162,247,.3)}.plan-card .plan-body p{margin:0 0 8px}.plan-card .plan-body p:last-child{margin-bottom:0}.plan-card .plan-body ul,.plan-card .plan-body ol{padding-left:22px;margin-bottom:8px}.plan-card .plan-body li{margin-bottom:5px}.plan-card .plan-body strong{color:#c0caf5}.tool-card{border:2px solid rgba(192,202,245,.24);border-left-width:6px;margin-bottom:8px;border-left-color:#7aa2f7;overflow:hidden;font-size:13px}.tool-card.is-success{border-left-color:#9ece6a}.tool-card.is-error{border-left-color:#f7768e}.tool-card>summary{list-style:none;display:flex;align-items:center;gap:8px;padding:5px 15px;cursor:pointer;background:#c0caf50b;color:#a9b1d6;-webkit-user-select:none;user-select:none}.tool-card>summary::-webkit-details-marker{display:none}.tool-card>summary:hover{background:#c0caf516}.tool-card>summary .tool-chevron{font-size:18px;color:#787c99;flex-shrink:0;transition:transform .15s ease}.tool-card[open]>summary .tool-chevron{transform:rotate(180deg)}.tool-card .tool-name{flex:1;font-family:IBM Plex Mono,monospace;font-size:12px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tool-card .tool-running-time{font-family:IBM Plex Mono,monospace;font-size:11px;color:#787c99;white-space:nowrap}.tool-card .tool-status-icon{display:flex;align-items:center;justify-content:center;width:18px;height:18px;font-size:18px;flex-shrink:0}.tool-card-body{background:#c0caf50b;border-top:2px solid rgba(192,202,245,.24)}.tool-running-banner{display:flex;align-items:center;gap:8px;padding:8px 15px;color:#a9b1d6;background:#7aa2f714;border-bottom:1px solid rgba(192,202,245,.24);font-size:12px}.tool-section{padding:8px 15px}.tool-section+.tool-section{border-top:1px solid rgba(192,202,245,.24)}.tool-section-label{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:#787c99;margin-bottom:5px}.tool-code{font-family:IBM Plex Mono,monospace;font-size:12px;color:#a9b1d6;white-space:pre-wrap;word-break:break-word}.tool-args summary{list-style:none;display:flex;align-items:center;gap:8px;padding:5px 15px;cursor:pointer;-webkit-user-select:none;user-select:none;font-size:12px;color:#a9b1d6;background:#c0caf50b}.tool-args summary::-webkit-details-marker{display:none}.tool-args summary:hover{background:#c0caf516}.tool-args summary .tool-chevron{margin-left:auto;font-size:18px;color:#787c99;transition:transform .15s ease}.tool-args[open]>summary .tool-chevron{transform:rotate(180deg)}.tool-cards-summary{display:inline-flex;align-items:center;gap:8px;padding:5px 0}.tool-fade-item{transition:none}.tool-fade-enter-active,.tool-fade-leave-active{transition:opacity .2s ease,transform .2s ease}.tool-fade-enter-from{opacity:0;transform:translateY(-4px)}.tool-fade-leave-to{opacity:0}@supports (interpolate-size: allow-keywords){details{interpolate-size:allow-keywords}details::details-content{block-size:0;overflow:clip;transition:block-size .25s ease,content-visibility .25s ease;transition-behavior:allow-discrete}details[open]::details-content{block-size:auto}}.tool-result{font-size:12px;line-height:1.5;color:#a9b1d6}.tool-result h1,.tool-result h2,.tool-result h3,.tool-result h4{color:#c0caf5;margin:8px 0}.tool-result p{margin:5px 0}.tool-result ul,.tool-result ol{padding-left:22px;margin:5px 0}.tool-result li{margin-bottom:2px}.tool-result blockquote{padding-left:8px;border-left:2px solid #7AA2F7;color:#a9b1d6;margin:5px 0}.tool-result code{font-family:IBM Plex Mono,monospace;background:#c0caf516;padding:1px 4px;color:#7dcfff;font-size:11px}.tool-result pre{margin:5px 0;background:#1f2335;border:2px solid rgba(192,202,245,.24);overflow:hidden}.tool-result pre code{display:block;padding:8px;overflow-x:auto}.result-line{font-family:IBM Plex Mono,monospace;padding:1px 0;white-space:pre-wrap;word-break:break-word}.json-object,.json-array{font-family:IBM Plex Mono,monospace;display:flex;flex-direction:column;gap:1px;padding:5px 0}.json-item{display:flex;align-items:baseline;gap:5px;padding:1px 0}.json-key{color:#c0caf5;font-weight:500;flex-shrink:0}.json-sep{color:#787c99}.json-value{color:#a9b1d6;word-break:break-word;white-space:pre-wrap}.json-string{color:#9ece6a}.json-number{color:#e0af68}.json-bool{color:#c0caf5}.json-null,.json-empty{color:#787c99;font-style:italic}.subagent-steps{display:flex;flex-direction:column;gap:5px;padding:5px 15px 15px;background:#c0caf50b}.subagent-planning-indicator{display:flex;align-items:center;gap:8px;padding:5px 15px;font-size:12px;font-style:italic;color:#787c99;background:#c0caf50b}.subagent-step{border:2px solid rgba(192,202,245,.24);border-left-width:6px;border-left-color:#7aa2f7;overflow:hidden;margin-bottom:8px;font-size:12px}.subagent-step.is-success{border-left-color:#9ece6a}.subagent-step.is-error{border-left-color:#f7768e}.subagent-step summary{list-style:none;display:flex;align-items:center;gap:8px;padding:5px 15px;cursor:pointer;background:#c0caf50b;color:#a9b1d6;-webkit-user-select:none;user-select:none}.subagent-step summary::-webkit-details-marker{display:none}.subagent-step summary:hover{background:#c0caf516}.subagent-step .tool-name{flex:1;font-family:IBM Plex Mono,monospace;font-size:12px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.subagent-step .tool-running-time{font-family:IBM Plex Mono,monospace;font-size:11px;color:#787c99;white-space:nowrap}.subagent-step .tool-status-icon{display:flex;align-items:center;justify-content:center;width:18px;height:18px;font-size:18px;flex-shrink:0}.subagent-step .tool-chevron{font-size:18px;color:#787c99;flex-shrink:0;transition:transform .15s ease}.subagent-step[open]>summary .tool-chevron{transform:rotate(180deg)}.summary-card{border:2px solid #BB9AF7;overflow:hidden;font-size:13px}.summary-card summary{list-style:none;display:flex;align-items:center;gap:8px;padding:8px 15px;cursor:pointer;background:#bb9af714;color:#bb9af7;-webkit-user-select:none;user-select:none}.summary-card summary::-webkit-details-marker{display:none}.compression-notice{font-size:12px}.compression-notice summary{list-style:none;text-align:center;padding:8px;color:#787c99;display:flex;align-items:center;justify-content:center;gap:8px;cursor:pointer;-webkit-user-select:none;user-select:none}.compression-notice summary::-webkit-details-marker{display:none}.compression-notice summary:before,.compression-notice summary:after{content:"";flex:1;height:1px;background:#c0caf53d}.compression-notice .compression-counts{opacity:.7}.compression-notice .compression-chevron{font-size:18px;transition:transform .15s ease}.compression-notice[open] .compression-chevron{transform:rotate(180deg)}.compression-notice .compression-body{padding:15px;font-size:13px;color:#a9b1d6;line-height:1.6;background:#c0caf50b;border:2px solid rgba(192,202,245,.24)}.input-bar{flex-shrink:0;padding:8px 15px;background:#16161e;border-top:2px solid rgba(192,202,245,.24)}.input-dropzone{position:relative}.input-dropzone.is-dragging:after{content:"Drop files here";position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center;background:#7aa2f71f;border:2px dashed #7AA2F7;font-size:14px;color:#7aa2f7;pointer-events:none;z-index:10}.file-preview-strip{display:flex;flex-wrap:wrap;gap:5px;margin-bottom:5px;max-width:920px;margin-left:auto;margin-right:auto}.file-preview-image{position:relative;width:60px;height:60px}.file-preview-image img{width:100%;height:100%;object-fit:cover;border:2px solid rgba(192,202,245,.24)}.file-preview-pill{display:inline-flex;align-items:center;gap:5px;padding:5px 8px;background:#c0caf50b;border:2px solid rgba(192,202,245,.24);font-size:12px;color:#a9b1d6;max-width:180px}.file-preview-pill span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.file-preview-remove{background:none;border:none;cursor:pointer;color:#787c99;padding:0;display:flex;align-items:center;font-size:14px;transition:color .15s ease;flex-shrink:0}.file-preview-remove:hover{color:#f7768e}.upload-progress{height:2px;background:#c0caf516;margin-bottom:5px;overflow:hidden}.upload-progress-fill{height:100%;background:#7aa2f7;transition:width .2s ease}.input-row{display:flex;align-items:center;gap:8px;background:#1f2335;border:2px solid rgba(192,202,245,.24);padding:8px;transition:border-color .15s ease;max-width:920px;margin:0 auto}.input-row:focus-within{border-color:#7aa2f7}.input-textarea{flex:1;background:none;border:none;outline:none;resize:none;color:#c0caf5;font-size:14px;line-height:1.5;font-family:inherit;min-height:24px;max-height:144px;overflow-y:auto;padding:2px 0}.input-textarea::placeholder{color:#787c99}.welcome-screen{flex:1;position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:34px;gap:34px;text-align:center}@media(max-width:768px){.welcome-screen{padding:52px 15px 15px;gap:15px;justify-content:flex-start}}.welcome-logo{display:flex;flex-direction:column;align-items:center;gap:8px}.welcome-logo img{width:64px;height:64px}.welcome-logo h1{font-size:32px;font-weight:700;letter-spacing:-.5px;color:#c0caf5;margin:0}.welcome-logo p{font-size:15px;color:#a9b1d6;margin:0}@media(max-width:768px){.welcome-logo{flex-direction:row;flex-wrap:wrap;justify-content:center;gap:8px}.welcome-logo img{width:36px;height:36px}.welcome-logo h1{font-size:22px}.welcome-logo p{font-size:13px;flex-basis:100%}}.welcome-profiles{display:flex;gap:15px;flex-wrap:wrap;justify-content:center;max-width:600px}@media(max-width:768px){.welcome-profiles{display:grid;grid-template-columns:repeat(2,1fr);gap:10px;width:100%;max-width:100%}}.welcome-profile-card{display:flex;flex-direction:column;align-items:center;gap:8px;padding:15px;background:#c0caf50b;border:2px solid rgba(192,202,245,.24);cursor:pointer;transition:border-color .15s ease,background .15s ease;width:160px;text-align:center}.welcome-profile-card:hover,.welcome-profile-card.is-selected{border-color:#7aa2f7;background:#c0caf516}.welcome-profile-card.is-selected{border-color:#7aa2f7}.welcome-profile-card .profile-icon{font-size:32px;color:#7aa2f7}.welcome-profile-card .profile-name{font-size:14px;font-weight:600;color:#c0caf5}.welcome-profile-card .profile-desc{font-size:12px;color:#787c99;line-height:1.4}@media(max-width:768px){.welcome-profile-card{width:auto;padding:10px;gap:6px}.welcome-profile-card .profile-icon{font-size:22px}.welcome-profile-card .profile-name{font-size:13px}.welcome-profile-card .profile-desc{font-size:11px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}}.empty-chat{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:15px;color:#787c99;padding:34px}.empty-chat .empty-icon{font-size:56px;opacity:.4}.empty-chat p{font-size:15px;margin:0}.spinner{display:inline-block;width:14px;height:14px;border:2px solid rgba(192,202,245,.24);border-top-color:#7aa2f7;border-radius:50%;animation:spin .6s linear infinite;flex-shrink:0}@keyframes spin{to{transform:rotate(360deg)}}.fade-enter-active,.fade-leave-active{transition:opacity .15s ease}.fade-enter-from,.fade-leave-to{opacity:0}.msg-enter{animation:msgEnter .2s ease both}@keyframes msgEnter{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.slide-left-enter-active,.slide-left-leave-active{transition:transform .28s ease,opacity .28s ease}.slide-left-enter-from,.slide-left-leave-to{transform:translate(-100%);opacity:0}.modal-enter-active,.modal-leave-active{transition:opacity .28s ease}.modal-enter-active .modal-panel,.modal-leave-active .modal-panel{transition:opacity .28s ease,margin-top .28s ease}.modal-enter-from,.modal-leave-to{opacity:0}.modal-enter-from .modal-panel,.modal-leave-to .modal-panel{opacity:0;margin-top:200px}.btn-icon:not(.with-rotate) .ph{transform:none!important;transition:none!important}.tool-card[open]>summary .tool-chevron,.thinking-card[open]>summary .tool-chevron{transform:rotate(180deg)!important}.msg-flash{animation:msgFlash 2.5s ease-out}@keyframes msgFlash{0%{filter:brightness(1)}15%{filter:brightness(1.4);background-color:#7aa2f71f}40%{filter:brightness(1.4);background-color:#7aa2f71f}to{filter:brightness(1)}}
diff --git a/webclient/dist/assets/index-C2n90a7h.js b/webclient/dist/assets/index-C2n90a7h.js
deleted file mode 100644
index 2f1d674..0000000
--- a/webclient/dist/assets/index-C2n90a7h.js
+++ /dev/null
@@ -1,112 +0,0 @@
-var PS=Object.defineProperty;var kS=(e,t,n)=>t in e?PS(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var ft=(e,t,n)=>kS(e,typeof t!="symbol"?t+"":t,n);(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const a of document.querySelectorAll('link[rel="modulepreload"]'))r(a);new MutationObserver(a=>{for(const i of a)if(i.type==="childList")for(const o of i.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&r(o)}).observe(document,{childList:!0,subtree:!0});function n(a){const i={};return a.integrity&&(i.integrity=a.integrity),a.referrerPolicy&&(i.referrerPolicy=a.referrerPolicy),a.crossOrigin==="use-credentials"?i.credentials="include":a.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function r(a){if(a.ep)return;a.ep=!0;const i=n(a);fetch(a.href,i)}})();/**
-* @vue/shared v3.5.32
-* (c) 2018-present Yuxi (Evan) You and Vue contributors
-* @license MIT
-**/function Yc(e){const t=Object.create(null);for(const n of e.split(","))t[n]=1;return n=>n in t}const bt={},Cr=[],Nn=()=>{},Rg=()=>!1,Wa=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Ka=e=>e.startsWith("onUpdate:"),Dt=Object.assign,qc=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},US=Object.prototype.hasOwnProperty,dt=(e,t)=>US.call(e,t),Fe=Array.isArray,Nr=e=>la(e)==="[object Map]",Cg=e=>la(e)==="[object Set]",M_=e=>la(e)==="[object Date]",Ve=e=>typeof e=="function",Ct=e=>typeof e=="string",jt=e=>typeof e=="symbol",pt=e=>e!==null&&typeof e=="object",Ng=e=>(pt(e)||Ve(e))&&Ve(e.then)&&Ve(e.catch),Og=Object.prototype.toString,la=e=>Og.call(e),FS=e=>la(e).slice(8,-1),yg=e=>la(e)==="[object Object]",Qa=e=>Ct(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,zr=Yc(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Xa=e=>{const t=Object.create(null);return(n=>t[n]||(t[n]=e(n)))},BS=/-\w/g,zt=Xa(e=>e.replace(BS,t=>t.slice(1).toUpperCase())),GS=/\B([A-Z])/g,Xn=Xa(e=>e.replace(GS,"-$1").toLowerCase()),Za=Xa(e=>e.charAt(0).toUpperCase()+e.slice(1)),Ca=Xa(e=>e?`on${Za(e)}`:""),vn=(e,t)=>!Object.is(e,t),Na=(e,...t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:r,value:n})},$c=e=>{const t=parseFloat(e);return isNaN(t)?e:t},YS=e=>{const t=Ct(e)?Number(e):NaN;return isNaN(t)?e:t};let L_;const Ja=()=>L_||(L_=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function On(e){if(Fe(e)){const t={};for(let n=0;n{if(n){const r=n.split($S);r.length>1&&(t[r[0].trim()]=r[1].trim())}}),t}function Ye(e){let t="";if(Ct(e))t=e;else if(Fe(e))for(let n=0;n!!(e&&e.__v_isRef===!0),xe=e=>Ct(e)?e:e==null?"":Fe(e)||pt(e)&&(e.toString===Og||!Ve(e.toString))?Dg(e)?xe(e.value):JSON.stringify(e,xg,2):String(e),xg=(e,t)=>Dg(t)?xg(e,t.value):Nr(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[r,a],i)=>(n[hi(r,i)+" =>"]=a,n),{})}:Cg(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>hi(n))}:jt(t)?hi(t):pt(t)&&!Fe(t)&&!yg(t)?String(t):t,hi=(e,t="")=>{var n;return jt(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/**
-* @vue/reactivity v3.5.32
-* (c) 2018-present Yuxi (Evan) You and Vue contributors
-* @license MIT
-**/let Ut;class Mg{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this.__v_skip=!0,this.parent=Ut,!t&&Ut&&(this.index=(Ut.scopes||(Ut.scopes=[])).push(this)-1)}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,n;if(this.scopes)for(t=0,n=this.scopes.length;t0&&--this._on===0&&(Ut=this.prevScope,this.prevScope=void 0)}stop(t){if(this._active){this._active=!1;let n,r;for(n=0,r=this.effects.length;n0)return;if(Kr){let t=Kr;for(Kr=void 0;t;){const n=t.next;t.next=void 0,t.flags&=-9,t=n}}let e;for(;Wr;){let t=Wr;for(Wr=void 0;t;){const n=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(r){e||(e=r)}t=n}}if(e)throw e}function Ug(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function Fg(e){let t,n=e.depsTail,r=n;for(;r;){const a=r.prevDep;r.version===-1?(r===n&&(n=a),Kc(r),ZS(r)):t=r,r.dep.activeLink=r.prevActiveLink,r.prevActiveLink=void 0,r=a}e.deps=t,e.depsTail=n}function Sc(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(Bg(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function Bg(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===ea)||(e.globalVersion=ea,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!Sc(e))))return;e.flags|=2;const t=e.dep,n=ht,r=cn;ht=e,cn=!0;try{Ug(e);const a=e.fn(e._value);(t.version===0||vn(a,e._value))&&(e.flags|=128,e._value=a,t.version++)}catch(a){throw t.version++,a}finally{ht=n,cn=r,Fg(e),e.flags&=-3}}function Kc(e,t=!1){const{dep:n,prevSub:r,nextSub:a}=e;if(r&&(r.nextSub=a,e.prevSub=void 0),a&&(a.prevSub=r,e.nextSub=void 0),n.subs===e&&(n.subs=r,!r&&n.computed)){n.computed.flags&=-5;for(let i=n.computed.deps;i;i=i.nextDep)Kc(i,!0)}!t&&!--n.sc&&n.map&&n.map.delete(n.key)}function ZS(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}let cn=!0;const Gg=[];function Fn(){Gg.push(cn),cn=!1}function Bn(){const e=Gg.pop();cn=e===void 0?!0:e}function w_(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const n=ht;ht=void 0;try{t()}finally{ht=n}}}let ea=0;class JS{constructor(t,n){this.sub=t,this.dep=n,this.version=n.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class Qc{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!ht||!cn||ht===this.computed)return;let n=this.activeLink;if(n===void 0||n.sub!==ht)n=this.activeLink=new JS(ht,this),ht.deps?(n.prevDep=ht.depsTail,ht.depsTail.nextDep=n,ht.depsTail=n):ht.deps=ht.depsTail=n,Yg(n);else if(n.version===-1&&(n.version=this.version,n.nextDep)){const r=n.nextDep;r.prevDep=n.prevDep,n.prevDep&&(n.prevDep.nextDep=r),n.prevDep=ht.depsTail,n.nextDep=void 0,ht.depsTail.nextDep=n,ht.depsTail=n,ht.deps===n&&(ht.deps=r)}return n}trigger(t){this.version++,ea++,this.notify(t)}notify(t){zc();try{for(let n=this.subs;n;n=n.prevSub)n.sub.notify()&&n.sub.dep.notify()}finally{Wc()}}}function Yg(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let r=t.deps;r;r=r.nextDep)Yg(r)}const n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}}const Da=new WeakMap,lr=Symbol(""),fc=Symbol(""),ta=Symbol("");function Ft(e,t,n){if(cn&&ht){let r=Da.get(e);r||Da.set(e,r=new Map);let a=r.get(n);a||(r.set(n,a=new Qc),a.map=r,a.key=n),a.track()}}function Ln(e,t,n,r,a,i){const o=Da.get(e);if(!o){ea++;return}const s=c=>{c&&c.trigger()};if(zc(),t==="clear")o.forEach(s);else{const c=Fe(e),l=c&&Qa(n);if(c&&n==="length"){const _=Number(r);o.forEach((d,u)=>{(u==="length"||u===ta||!jt(u)&&u>=_)&&s(d)})}else switch((n!==void 0||o.has(void 0))&&s(o.get(n)),l&&s(o.get(ta)),t){case"add":c?l&&s(o.get("length")):(s(o.get(lr)),Nr(e)&&s(o.get(fc)));break;case"delete":c||(s(o.get(lr)),Nr(e)&&s(o.get(fc)));break;case"set":Nr(e)&&s(o.get(lr));break}}Wc()}function jS(e,t){const n=Da.get(e);return n&&n.get(t)}function fr(e){const t=at(e);return t===e?t:(Ft(t,"iterate",ta),Zt(e)?t:t.map(_n))}function ja(e){return Ft(e=at(e),"iterate",ta),e}function Tn(e,t){return Gn(e)?Ir(Un(e)?_n(t):t):_n(t)}const ef={__proto__:null,[Symbol.iterator](){return Ri(this,Symbol.iterator,e=>Tn(this,e))},concat(...e){return fr(this).concat(...e.map(t=>Fe(t)?fr(t):t))},entries(){return Ri(this,"entries",e=>(e[1]=Tn(this,e[1]),e))},every(e,t){return Dn(this,"every",e,t,void 0,arguments)},filter(e,t){return Dn(this,"filter",e,t,n=>n.map(r=>Tn(this,r)),arguments)},find(e,t){return Dn(this,"find",e,t,n=>Tn(this,n),arguments)},findIndex(e,t){return Dn(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return Dn(this,"findLast",e,t,n=>Tn(this,n),arguments)},findLastIndex(e,t){return Dn(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return Dn(this,"forEach",e,t,void 0,arguments)},includes(...e){return Ci(this,"includes",e)},indexOf(...e){return Ci(this,"indexOf",e)},join(e){return fr(this).join(e)},lastIndexOf(...e){return Ci(this,"lastIndexOf",e)},map(e,t){return Dn(this,"map",e,t,void 0,arguments)},pop(){return Fr(this,"pop")},push(...e){return Fr(this,"push",e)},reduce(e,...t){return P_(this,"reduce",e,t)},reduceRight(e,...t){return P_(this,"reduceRight",e,t)},shift(){return Fr(this,"shift")},some(e,t){return Dn(this,"some",e,t,void 0,arguments)},splice(...e){return Fr(this,"splice",e)},toReversed(){return fr(this).toReversed()},toSorted(e){return fr(this).toSorted(e)},toSpliced(...e){return fr(this).toSpliced(...e)},unshift(...e){return Fr(this,"unshift",e)},values(){return Ri(this,"values",e=>Tn(this,e))}};function Ri(e,t,n){const r=ja(e),a=r[t]();return r!==e&&!Zt(e)&&(a._next=a.next,a.next=()=>{const i=a._next();return i.done||(i.value=n(i.value)),i}),a}const tf=Array.prototype;function Dn(e,t,n,r,a,i){const o=ja(e),s=o!==e&&!Zt(e),c=o[t];if(c!==tf[t]){const d=c.apply(e,i);return s?_n(d):d}let l=n;o!==e&&(s?l=function(d,u){return n.call(this,Tn(e,d),u,e)}:n.length>2&&(l=function(d,u){return n.call(this,d,u,e)}));const _=c.call(o,l,r);return s&&a?a(_):_}function P_(e,t,n,r){const a=ja(e),i=a!==e&&!Zt(e);let o=n,s=!1;a!==e&&(i?(s=r.length===0,o=function(l,_,d){return s&&(s=!1,l=Tn(e,l)),n.call(this,l,Tn(e,_),d,e)}):n.length>3&&(o=function(l,_,d){return n.call(this,l,_,d,e)}));const c=a[t](o,...r);return s?Tn(e,c):c}function Ci(e,t,n){const r=at(e);Ft(r,"iterate",ta);const a=r[t](...n);return(a===-1||a===!1)&&ei(n[0])?(n[0]=at(n[0]),r[t](...n)):a}function Fr(e,t,n=[]){Fn(),zc();const r=at(e)[t].apply(e,n);return Wc(),Bn(),r}const nf=Yc("__proto__,__v_isRef,__isVue"),qg=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(jt));function rf(e){jt(e)||(e=String(e));const t=at(this);return Ft(t,"has",e),t.hasOwnProperty(e)}class $g{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,r){if(n==="__v_skip")return t.__v_skip;const a=this._isReadonly,i=this._isShallow;if(n==="__v_isReactive")return!a;if(n==="__v_isReadonly")return a;if(n==="__v_isShallow")return i;if(n==="__v_raw")return r===(a?i?mf:Wg:i?zg:Vg).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(r)?t:void 0;const o=Fe(t);if(!a){let c;if(o&&(c=ef[n]))return c;if(n==="hasOwnProperty")return rf}const s=Reflect.get(t,n,Nt(t)?t:r);if((jt(n)?qg.has(n):nf(n))||(a||Ft(t,"get",n),i))return s;if(Nt(s)){const c=o&&Qa(n)?s:s.value;return a&&pt(c)?Tc(c):c}return pt(s)?a?Tc(s):ca(s):s}}class Hg extends $g{constructor(t=!1){super(!1,t)}set(t,n,r,a){let i=t[n];const o=Fe(t)&&Qa(n);if(!this._isShallow){const l=Gn(i);if(!Zt(r)&&!Gn(r)&&(i=at(i),r=at(r)),!o&&Nt(i)&&!Nt(r))return l||(i.value=r),!0}const s=o?Number(n)e,Sa=e=>Reflect.getPrototypeOf(e);function cf(e,t,n){return function(...r){const a=this.__v_raw,i=at(a),o=Nr(i),s=e==="entries"||e===Symbol.iterator&&o,c=e==="keys"&&o,l=a[e](...r),_=n?bc:t?Ir:_n;return!t&&Ft(i,"iterate",c?fc:lr),Dt(Object.create(l),{next(){const{value:d,done:u}=l.next();return u?{value:d,done:u}:{value:s?[_(d[0]),_(d[1])]:_(d),done:u}}})}}function fa(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function _f(e,t){const n={get(a){const i=this.__v_raw,o=at(i),s=at(a);e||(vn(a,s)&&Ft(o,"get",a),Ft(o,"get",s));const{has:c}=Sa(o),l=t?bc:e?Ir:_n;if(c.call(o,a))return l(i.get(a));if(c.call(o,s))return l(i.get(s));i!==o&&i.get(a)},get size(){const a=this.__v_raw;return!e&&Ft(at(a),"iterate",lr),a.size},has(a){const i=this.__v_raw,o=at(i),s=at(a);return e||(vn(a,s)&&Ft(o,"has",a),Ft(o,"has",s)),a===s?i.has(a):i.has(a)||i.has(s)},forEach(a,i){const o=this,s=o.__v_raw,c=at(s),l=t?bc:e?Ir:_n;return!e&&Ft(c,"iterate",lr),s.forEach((_,d)=>a.call(i,l(_),l(d),o))}};return Dt(n,e?{add:fa("add"),set:fa("set"),delete:fa("delete"),clear:fa("clear")}:{add(a){const i=at(this),o=Sa(i),s=at(a),c=!t&&!Zt(a)&&!Gn(a)?s:a;return o.has.call(i,c)||vn(a,c)&&o.has.call(i,a)||vn(s,c)&&o.has.call(i,s)||(i.add(c),Ln(i,"add",c,c)),this},set(a,i){!t&&!Zt(i)&&!Gn(i)&&(i=at(i));const o=at(this),{has:s,get:c}=Sa(o);let l=s.call(o,a);l||(a=at(a),l=s.call(o,a));const _=c.call(o,a);return o.set(a,i),l?vn(i,_)&&Ln(o,"set",a,i):Ln(o,"add",a,i),this},delete(a){const i=at(this),{has:o,get:s}=Sa(i);let c=o.call(i,a);c||(a=at(a),c=o.call(i,a)),s&&s.call(i,a);const l=i.delete(a);return c&&Ln(i,"delete",a,void 0),l},clear(){const a=at(this),i=a.size!==0,o=a.clear();return i&&Ln(a,"clear",void 0,void 0),o}}),["keys","values","entries",Symbol.iterator].forEach(a=>{n[a]=cf(a,e,t)}),n}function Xc(e,t){const n=_f(e,t);return(r,a,i)=>a==="__v_isReactive"?!e:a==="__v_isReadonly"?e:a==="__v_raw"?r:Reflect.get(dt(n,a)&&a in r?n:r,a,i)}const df={get:Xc(!1,!1)},uf={get:Xc(!1,!0)},pf={get:Xc(!0,!1)};const Vg=new WeakMap,zg=new WeakMap,Wg=new WeakMap,mf=new WeakMap;function gf(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Ef(e){return e.__v_skip||!Object.isExtensible(e)?0:gf(FS(e))}function ca(e){return Gn(e)?e:Zc(e,!1,of,df,Vg)}function Kg(e){return Zc(e,!1,lf,uf,zg)}function Tc(e){return Zc(e,!0,sf,pf,Wg)}function Zc(e,t,n,r,a){if(!pt(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const i=Ef(e);if(i===0)return e;const o=a.get(e);if(o)return o;const s=new Proxy(e,i===2?r:n);return a.set(e,s),s}function Un(e){return Gn(e)?Un(e.__v_raw):!!(e&&e.__v_isReactive)}function Gn(e){return!!(e&&e.__v_isReadonly)}function Zt(e){return!!(e&&e.__v_isShallow)}function ei(e){return e?!!e.__v_raw:!1}function at(e){const t=e&&e.__v_raw;return t?at(t):e}function ti(e){return!dt(e,"__v_skip")&&Object.isExtensible(e)&&Ig(e,"__v_skip",!0),e}const _n=e=>pt(e)?ca(e):e,Ir=e=>pt(e)?Tc(e):e;function Nt(e){return e?e.__v_isRef===!0:!1}function X(e){return Qg(e,!1)}function Rr(e){return Qg(e,!0)}function Qg(e,t){return Nt(e)?e:new Sf(e,t)}class Sf{constructor(t,n){this.dep=new Qc,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=n?t:at(t),this._value=n?t:_n(t),this.__v_isShallow=n}get value(){return this.dep.track(),this._value}set value(t){const n=this._rawValue,r=this.__v_isShallow||Zt(t)||Gn(t);t=r?t:at(t),vn(t,n)&&(this._rawValue=t,this._value=r?t:_n(t),this.dep.trigger())}}function K(e){return Nt(e)?e.value:e}function ge(e){return Ve(e)?e():K(e)}const ff={get:(e,t,n)=>t==="__v_raw"?e:K(Reflect.get(e,t,n)),set:(e,t,n,r)=>{const a=e[t];return Nt(a)&&!Nt(n)?(a.value=n,!0):Reflect.set(e,t,n,r)}};function Xg(e){return Un(e)?e:new Proxy(e,ff)}function bf(e){const t=Fe(e)?new Array(e.length):{};for(const n in e)t[n]=hf(e,n);return t}class Tf{constructor(t,n,r){this._object=t,this._defaultValue=r,this.__v_isRef=!0,this._value=void 0,this._key=jt(n)?n:String(n),this._raw=at(t);let a=!0,i=t;if(!Fe(t)||jt(this._key)||!Qa(this._key))do a=!ei(i)||Zt(i);while(a&&(i=i.__v_raw));this._shallow=a}get value(){let t=this._object[this._key];return this._shallow&&(t=K(t)),this._value=t===void 0?this._defaultValue:t}set value(t){if(this._shallow&&Nt(this._raw[this._key])){const n=this._object[this._key];if(Nt(n)){n.value=t;return}}this._object[this._key]=t}get dep(){return jS(this._raw,this._key)}}function hf(e,t,n){return new Tf(e,t,n)}class vf{constructor(t,n,r){this.fn=t,this.setter=n,this._value=void 0,this.dep=new Qc(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=ea-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!n,this.isSSR=r}notify(){if(this.flags|=16,!(this.flags&8)&&ht!==this)return kg(this,!0),!0}get value(){const t=this.dep.track();return Bg(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function Rf(e,t,n=!1){let r,a;return Ve(e)?r=e:(r=e.get,a=e.set),new vf(r,a,n)}const ba={},xa=new WeakMap;let rr;function Cf(e,t=!1,n=rr){if(n){let r=xa.get(n);r||xa.set(n,r=[]),r.push(e)}}function Nf(e,t,n=bt){const{immediate:r,deep:a,once:i,scheduler:o,augmentJob:s,call:c}=n,l=D=>a?D:Zt(D)||a===!1||a===0?wn(D,1):wn(D);let _,d,u,m,p=!1,E=!1;if(Nt(e)?(d=()=>e.value,p=Zt(e)):Un(e)?(d=()=>l(e),p=!0):Fe(e)?(E=!0,p=e.some(D=>Un(D)||Zt(D)),d=()=>e.map(D=>{if(Nt(D))return D.value;if(Un(D))return l(D);if(Ve(D))return c?c(D,2):D()})):Ve(e)?t?d=c?()=>c(e,2):e:d=()=>{if(u){Fn();try{u()}finally{Bn()}}const D=rr;rr=_;try{return c?c(e,3,[m]):e(m)}finally{rr=D}}:d=Nn,t&&a){const D=d,L=a===!0?1/0:a;d=()=>wn(D(),L)}const S=Lg(),b=()=>{_.stop(),S&&S.active&&qc(S.effects,_)};if(i&&t){const D=t;t=(...L)=>{D(...L),b()}}let h=E?new Array(e.length).fill(ba):ba;const A=D=>{if(!(!(_.flags&1)||!_.dirty&&!D))if(t){const L=_.run();if(a||p||(E?L.some((y,I)=>vn(y,h[I])):vn(L,h))){u&&u();const y=rr;rr=_;try{const I=[L,h===ba?void 0:E&&h[0]===ba?[]:h,m];h=L,c?c(t,3,I):t(...I)}finally{rr=y}}}else _.run()};return s&&s(A),_=new wg(d),_.scheduler=o?()=>o(A,!1):A,m=D=>Cf(D,!1,_),u=_.onStop=()=>{const D=xa.get(_);if(D){if(c)c(D,4);else for(const L of D)L();xa.delete(_)}},t?r?A(!0):h=_.run():o?o(A.bind(null,!0),!0):_.run(),b.pause=_.pause.bind(_),b.resume=_.resume.bind(_),b.stop=b,b}function wn(e,t=1/0,n){if(t<=0||!pt(e)||e.__v_skip||(n=n||new Map,(n.get(e)||0)>=t))return e;if(n.set(e,t),t--,Nt(e))wn(e.value,t,n);else if(Fe(e))for(let r=0;r{wn(r,t,n)});else if(yg(e)){for(const r in e)wn(e[r],t,n);for(const r of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,r)&&wn(e[r],t,n)}return e}/**
-* @vue/runtime-core v3.5.32
-* (c) 2018-present Yuxi (Evan) You and Vue contributors
-* @license MIT
-**/function _a(e,t,n,r){try{return r?e(...r):e()}catch(a){ni(a,t,n)}}function dn(e,t,n,r){if(Ve(e)){const a=_a(e,t,n,r);return a&&Ng(a)&&a.catch(i=>{ni(i,t,n)}),a}if(Fe(e)){const a=[];for(let i=0;i>>1,a=Ht[r],i=na(a);i=na(n)?Ht.push(e):Ht.splice(yf(t),0,e),e.flags|=1,Jg()}}function Jg(){Ma||(Ma=Zg.then(eE))}function If(e){Fe(e)?Or.push(...e):Kn&&e.id===-1?Kn.splice(Tr+1,0,e):e.flags&1||(Or.push(e),e.flags|=1),Jg()}function k_(e,t,n=fn+1){for(;nna(n)-na(r));if(Or.length=0,Kn){Kn.push(...t);return}for(Kn=t,Tr=0;Tre.id==null?e.flags&2?-1:1/0:e.id;function eE(e){try{for(fn=0;fn{r._d&&ka(-1);const i=La(t);let o;try{o=e(...a)}finally{La(i),r._d&&ka(1)}return o};return r._n=!0,r._c=!0,r._d=!0,r}function nE(e,t){if(wt===null)return e;const n=_i(wt),r=e.dirs||(e.dirs=[]);for(let a=0;a1)return n&&Ve(t)?t.call(r&&r.proxy):t}}function Af(){return!!(ci()||_r)}const Df=Symbol.for("v-scx"),xf=()=>cr(Df);function $e(e,t,n){return rE(e,t,n)}function rE(e,t,n=bt){const{immediate:r,deep:a,flush:i,once:o}=n,s=Dt({},n),c=t&&r||!t&&i!=="post";let l;if(oa){if(i==="sync"){const m=xf();l=m.__watcherHandles||(m.__watcherHandles=[])}else if(!c){const m=()=>{};return m.stop=Nn,m.resume=Nn,m.pause=Nn,m}}const _=Gt;s.call=(m,p,E)=>dn(m,_,p,E);let d=!1;i==="post"?s.scheduler=m=>{$t(m,_&&_.suspense)}:i!=="sync"&&(d=!0,s.scheduler=(m,p)=>{p?m():Jc(m)}),s.augmentJob=m=>{t&&(m.flags|=4),d&&(m.flags|=2,_&&(m.id=_.uid,m.i=_))};const u=Nf(e,t,s);return oa&&(l?l.push(u):c&&u()),u}function Mf(e,t,n){const r=this.proxy,a=Ct(e)?e.includes(".")?aE(r,e):()=>r[e]:e.bind(r,r);let i;Ve(t)?i=t:(i=t.handler,n=t);const o=da(this),s=rE(a,i.bind(r),n);return o(),s}function aE(e,t){const n=t.split(".");return()=>{let r=e;for(let a=0;ae.__isTeleport,ir=e=>e&&(e.disabled||e.disabled===""),Lf=e=>e&&(e.defer||e.defer===""),U_=e=>typeof SVGElement<"u"&&e instanceof SVGElement,F_=e=>typeof MathMLElement=="function"&&e instanceof MathMLElement,hc=(e,t)=>{const n=e&&e.to;return Ct(n)?t?t(n):null:n},wf={name:"Teleport",__isTeleport:!0,process(e,t,n,r,a,i,o,s,c,l){const{mc:_,pc:d,pbc:u,o:{insert:m,querySelector:p,createText:E,createComment:S}}=l,b=ir(t.props);let{dynamicChildren:h}=t;const A=(y,I,v)=>{y.shapeFlag&16&&_(y.children,I,v,a,i,o,s,c)},D=(y=t)=>{const I=ir(y.props),v=y.target=hc(y.props,p),C=vc(v,y,E,m);v&&(o!=="svg"&&U_(v)?o="svg":o!=="mathml"&&F_(v)&&(o="mathml"),a&&a.isCE&&(a.ce._teleportTargets||(a.ce._teleportTargets=new Set)).add(v),I||(A(y,v,C),$r(y,!1)))},L=y=>{const I=()=>{er.get(y)===I&&(er.delete(y),ir(y.props)&&(A(y,n,y.anchor),$r(y,!0)),D(y))};er.set(y,I),$t(I,i)};if(e==null){const y=t.el=E(""),I=t.anchor=E("");if(m(y,n,r),m(I,n,r),Lf(t.props)||i&&i.pendingBranch){L(t);return}b&&(A(t,n,I),$r(t,!0)),D()}else{t.el=e.el;const y=t.anchor=e.anchor,I=er.get(e);if(I){I.flags|=8,er.delete(e),L(t);return}t.targetStart=e.targetStart;const v=t.target=e.target,C=t.targetAnchor=e.targetAnchor,P=ir(e.props),U=P?n:v,x=P?y:C;if(o==="svg"||U_(v)?o="svg":(o==="mathml"||F_(v))&&(o="mathml"),h?(u(e.dynamicChildren,h,U,a,i,o,s),r_(e,t,!0)):c||d(e,t,U,x,a,i,o,s,!1),b)P?t.props&&e.props&&t.props.to!==e.props.to&&(t.props.to=e.props.to):Ta(t,n,y,l,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const j=t.target=hc(t.props,p);j&&Ta(t,j,null,l,0)}else P&&Ta(t,v,C,l,1);$r(t,b)}},remove(e,t,n,{um:r,o:{remove:a}},i){const{shapeFlag:o,children:s,anchor:c,targetStart:l,targetAnchor:_,target:d,props:u}=e;let m=i||!ir(u);const p=er.get(e);if(p&&(p.flags|=8,er.delete(e),m=!1),d&&(a(l),a(_)),i&&a(c),o&16)for(let E=0;E{e.isMounted=!0}),Kt(()=>{e.isUnmounting=!0}),e}const on=[Function,Array],lE={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:on,onEnter:on,onAfterEnter:on,onEnterCancelled:on,onBeforeLeave:on,onLeave:on,onAfterLeave:on,onLeaveCancelled:on,onBeforeAppear:on,onAppear:on,onAfterAppear:on,onAppearCancelled:on},cE=e=>{const t=e.subTree;return t.component?cE(t.component):t},kf={name:"BaseTransition",props:lE,setup(e,{slots:t}){const n=ci(),r=sE();return()=>{const a=t.default&&jc(t.default(),!0);if(!a||!a.length)return;const i=_E(a),o=at(e),{mode:s}=o;if(r.isLeaving)return Ni(i);const c=B_(i);if(!c)return Ni(i);let l=ra(c,o,r,n,d=>l=d);c.type!==Bt&&ur(c,l);let _=n.subTree&&B_(n.subTree);if(_&&_.type!==Bt&&!or(_,c)&&cE(n).type!==Bt){let d=ra(_,o,r,n);if(ur(_,d),s==="out-in"&&c.type!==Bt)return r.isLeaving=!0,d.afterLeave=()=>{r.isLeaving=!1,n.job.flags&8||n.update(),delete d.afterLeave,_=void 0},Ni(i);s==="in-out"&&c.type!==Bt?d.delayLeave=(u,m,p)=>{const E=dE(r,_);E[String(_.key)]=_,u[bn]=()=>{m(),u[bn]=void 0,delete l.delayedLeave,_=void 0},l.delayedLeave=()=>{p(),delete l.delayedLeave,_=void 0}}:_=void 0}else _&&(_=void 0);return i}}};function _E(e){let t=e[0];if(e.length>1){for(const n of e)if(n.type!==Bt){t=n;break}}return t}const Uf=kf;function dE(e,t){const{leavingVNodes:n}=e;let r=n.get(t.type);return r||(r=Object.create(null),n.set(t.type,r)),r}function ra(e,t,n,r,a){const{appear:i,mode:o,persisted:s=!1,onBeforeEnter:c,onEnter:l,onAfterEnter:_,onEnterCancelled:d,onBeforeLeave:u,onLeave:m,onAfterLeave:p,onLeaveCancelled:E,onBeforeAppear:S,onAppear:b,onAfterAppear:h,onAppearCancelled:A}=t,D=String(e.key),L=dE(n,e),y=(C,P)=>{C&&dn(C,r,9,P)},I=(C,P)=>{const U=P[1];y(C,P),Fe(C)?C.every(x=>x.length<=1)&&U():C.length<=1&&U()},v={mode:o,persisted:s,beforeEnter(C){let P=c;if(!n.isMounted)if(i)P=S||c;else return;C[bn]&&C[bn](!0);const U=L[D];U&&or(e,U)&&U.el[bn]&&U.el[bn](),y(P,[C])},enter(C){if(L[D]===e)return;let P=l,U=_,x=d;if(!n.isMounted)if(i)P=b||l,U=h||_,x=A||d;else return;let j=!1;C[Br]=he=>{j||(j=!0,he?y(x,[C]):y(U,[C]),v.delayedLeave&&v.delayedLeave(),C[Br]=void 0)};const ie=C[Br].bind(null,!1);P?I(P,[C,ie]):ie()},leave(C,P){const U=String(e.key);if(C[Br]&&C[Br](!0),n.isUnmounting)return P();y(u,[C]);let x=!1;C[bn]=ie=>{x||(x=!0,P(),ie?y(E,[C]):y(p,[C]),C[bn]=void 0,L[U]===e&&delete L[U])};const j=C[bn].bind(null,!1);L[U]=e,m?I(m,[C,j]):j()},clone(C){const P=ra(C,t,n,r,a);return a&&a(P),P}};return v}function Ni(e){if(ai(e))return e=Qn(e),e.children=null,e}function B_(e){if(!ai(e))return oE(e.type)&&e.children?_E(e.children):e;if(e.component)return e.component.subTree;const{shapeFlag:t,children:n}=e;if(n){if(t&16)return n[0];if(t&32&&Ve(n.default))return n.default()}}function ur(e,t){e.shapeFlag&6&&e.component?(e.transition=t,ur(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function jc(e,t=!1,n){let r=[],a=0;for(let i=0;i1)for(let i=0;iQr(E,t&&(Fe(t)?t[S]:t),n,r,a));return}if(yr(r)&&!a){r.shapeFlag&512&&r.type.__asyncResolved&&r.component.subTree.component&&Qr(e,t,n,r.component.subTree);return}const i=r.shapeFlag&4?_i(r.component):r.el,o=a?null:i,{i:s,r:c}=e,l=t&&t.r,_=s.refs===bt?s.refs={}:s.refs,d=s.setupState,u=at(d),m=d===bt?Rg:E=>G_(_,E)?!1:dt(u,E),p=(E,S)=>!(S&&G_(_,S));if(l!=null&&l!==c){if(Y_(t),Ct(l))_[l]=null,m(l)&&(d[l]=null);else if(Nt(l)){const E=t;p(l,E.k)&&(l.value=null),E.k&&(_[E.k]=null)}}if(Ve(c))_a(c,s,12,[o,_]);else{const E=Ct(c),S=Nt(c);if(E||S){const b=()=>{if(e.f){const h=E?m(c)?d[c]:_[c]:p()||!e.k?c.value:_[e.k];if(a)Fe(h)&&qc(h,i);else if(Fe(h))h.includes(i)||h.push(i);else if(E)_[c]=[i],m(c)&&(d[c]=_[c]);else{const A=[i];p(c,e.k)&&(c.value=A),e.k&&(_[e.k]=A)}}else E?(_[c]=o,m(c)&&(d[c]=o)):S&&(p(c,e.k)&&(c.value=o),e.k&&(_[e.k]=o))};if(o){const h=()=>{b(),wa.delete(e)};h.id=-1,wa.set(e,h),$t(h,n)}else Y_(e),b()}}}function Y_(e){const t=wa.get(e);t&&(t.flags|=8,wa.delete(e))}Ja().requestIdleCallback;Ja().cancelIdleCallback;const yr=e=>!!e.type.__asyncLoader,ai=e=>e.type.__isKeepAlive;function e_(e,t){mE(e,"a",t)}function pE(e,t){mE(e,"da",t)}function mE(e,t,n=Gt){const r=e.__wdc||(e.__wdc=()=>{let a=n;for(;a;){if(a.isDeactivated)return;a=a.parent}return e()});if(ii(t,r,n),n){let a=n.parent;for(;a&&a.parent;)ai(a.parent.vnode)&&Ff(r,t,n,a),a=a.parent}}function Ff(e,t,n,r){const a=ii(t,e,r,!0);gr(()=>{qc(r[t],a)},n)}function ii(e,t,n=Gt,r=!1){if(n){const a=n[e]||(n[e]=[]),i=t.__weh||(t.__weh=(...o)=>{Fn();const s=da(n),c=dn(t,n,e,o);return s(),Bn(),c});return r?a.unshift(i):a.push(i),i}}const Yn=e=>(t,n=Gt)=>{(!oa||e==="sp")&&ii(e,(...r)=>t(...r),n)},Bf=Yn("bm"),un=Yn("m"),Gf=Yn("bu"),gE=Yn("u"),Kt=Yn("bum"),gr=Yn("um"),Yf=Yn("sp"),qf=Yn("rtg"),$f=Yn("rtc");function Hf(e,t=Gt){ii("ec",e,t)}const EE="components";function Pt(e,t){return fE(EE,e,!0,t)||e}const SE=Symbol.for("v-ndc");function oi(e){return Ct(e)?fE(EE,e,!1)||e:e||SE}function fE(e,t,n=!0,r=!1){const a=wt||Gt;if(a){const i=a.type;{const s=Ab(i,!1);if(s&&(s===t||s===zt(t)||s===Za(zt(t))))return i}const o=q_(a[e]||i[e],t)||q_(a.appContext[e],t);return!o&&r?i:o}}function q_(e,t){return e&&(e[t]||e[zt(t)]||e[Za(zt(t))])}function Jt(e,t,n,r){let a;const i=n,o=Fe(e);if(o||Ct(e)){const s=o&&Un(e);let c=!1,l=!1;s&&(c=!Zt(e),l=Gn(e),e=ja(e)),a=new Array(e.length);for(let _=0,d=e.length;_t(s,c,void 0,i));else{const s=Object.keys(e);a=new Array(s.length);for(let c=0,l=s.length;c{const i=r.fn(...a);return i&&(i.key=r.key),i}:r.fn)}return e}function Rn(e,t,n={},r,a){if(wt.ce||wt.parent&&yr(wt.parent)&&wt.parent.ce){const l=Object.keys(n).length>0;return t!=="default"&&(n.name=t),M(),ut(et,null,[ke("slot",n,r)],l?-2:64)}let i=e[t];i&&i._c&&(i._d=!1),M();const o=i&&bE(i(n)),s=n.key||o&&o.key,c=ut(et,{key:(s&&!jt(s)?s:`_${t}`)+(!o&&r?"_fb":"")},o||[],o&&e._===1?64:-2);return c.scopeId&&(c.slotScopeIds=[c.scopeId+"-s"]),i&&i._c&&(i._d=!0),c}function bE(e){return e.some(t=>ia(t)?!(t.type===Bt||t.type===et&&!bE(t.children)):!0)?e:null}function zf(e,t){const n={};for(const r in e)n[Ca(r)]=e[r];return n}const Rc=e=>e?BE(e)?_i(e):Rc(e.parent):null,Xr=Dt(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>Rc(e.parent),$root:e=>Rc(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>hE(e),$forceUpdate:e=>e.f||(e.f=()=>{Jc(e.update)}),$nextTick:e=>e.n||(e.n=Lt.bind(e.proxy)),$watch:e=>Mf.bind(e)}),Oi=(e,t)=>e!==bt&&!e.__isScriptSetup&&dt(e,t),Wf={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:n,setupState:r,data:a,props:i,accessCache:o,type:s,appContext:c}=e;if(t[0]!=="$"){const u=o[t];if(u!==void 0)switch(u){case 1:return r[t];case 2:return a[t];case 4:return n[t];case 3:return i[t]}else{if(Oi(r,t))return o[t]=1,r[t];if(a!==bt&&dt(a,t))return o[t]=2,a[t];if(dt(i,t))return o[t]=3,i[t];if(n!==bt&&dt(n,t))return o[t]=4,n[t];Cc&&(o[t]=0)}}const l=Xr[t];let _,d;if(l)return t==="$attrs"&&Ft(e.attrs,"get",""),l(e);if((_=s.__cssModules)&&(_=_[t]))return _;if(n!==bt&&dt(n,t))return o[t]=4,n[t];if(d=c.config.globalProperties,dt(d,t))return d[t]},set({_:e},t,n){const{data:r,setupState:a,ctx:i}=e;return Oi(a,t)?(a[t]=n,!0):r!==bt&&dt(r,t)?(r[t]=n,!0):dt(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(i[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:r,appContext:a,props:i,type:o}},s){let c;return!!(n[s]||e!==bt&&s[0]!=="$"&&dt(e,s)||Oi(t,s)||dt(i,s)||dt(r,s)||dt(Xr,s)||dt(a.config.globalProperties,s)||(c=o.__cssModules)&&c[s])},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:dt(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function $_(e){return Fe(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Cc=!0;function Kf(e){const t=hE(e),n=e.proxy,r=e.ctx;Cc=!1,t.beforeCreate&&H_(t.beforeCreate,e,"bc");const{data:a,computed:i,methods:o,watch:s,provide:c,inject:l,created:_,beforeMount:d,mounted:u,beforeUpdate:m,updated:p,activated:E,deactivated:S,beforeDestroy:b,beforeUnmount:h,destroyed:A,unmounted:D,render:L,renderTracked:y,renderTriggered:I,errorCaptured:v,serverPrefetch:C,expose:P,inheritAttrs:U,components:x,directives:j,filters:ie}=t;if(l&&Qf(l,r,null),o)for(const ue in o){const Ne=o[ue];Ve(Ne)&&(r[ue]=Ne.bind(n))}if(a){const ue=a.call(n,n);pt(ue)&&(e.data=ca(ue))}if(Cc=!0,i)for(const ue in i){const Ne=i[ue],ve=Ve(Ne)?Ne.bind(n,n):Ve(Ne.get)?Ne.get.bind(n,n):Nn,Le=!Ve(Ne)&&Ve(Ne.set)?Ne.set.bind(n):Nn,Xe=pe({get:ve,set:Le});Object.defineProperty(r,ue,{enumerable:!0,configurable:!0,get:()=>Xe.value,set:ze=>Xe.value=ze})}if(s)for(const ue in s)TE(s[ue],r,n,ue);if(c){const ue=Ve(c)?c.call(n):c;Reflect.ownKeys(ue).forEach(Ne=>{ar(Ne,ue[Ne])})}_&&H_(_,e,"c");function ae(ue,Ne){Fe(Ne)?Ne.forEach(ve=>ue(ve.bind(n))):Ne&&ue(Ne.bind(n))}if(ae(Bf,d),ae(un,u),ae(Gf,m),ae(gE,p),ae(e_,E),ae(pE,S),ae(Hf,v),ae($f,y),ae(qf,I),ae(Kt,h),ae(gr,D),ae(Yf,C),Fe(P))if(P.length){const ue=e.exposed||(e.exposed={});P.forEach(Ne=>{Object.defineProperty(ue,Ne,{get:()=>n[Ne],set:ve=>n[Ne]=ve,enumerable:!0})})}else e.exposed||(e.exposed={});L&&e.render===Nn&&(e.render=L),U!=null&&(e.inheritAttrs=U),x&&(e.components=x),j&&(e.directives=j),C&&uE(e)}function Qf(e,t,n=Nn){Fe(e)&&(e=Nc(e));for(const r in e){const a=e[r];let i;pt(a)?"default"in a?i=cr(a.from||r,a.default,!0):i=cr(a.from||r):i=cr(a),Nt(i)?Object.defineProperty(t,r,{enumerable:!0,configurable:!0,get:()=>i.value,set:o=>i.value=o}):t[r]=i}}function H_(e,t,n){dn(Fe(e)?e.map(r=>r.bind(t.proxy)):e.bind(t.proxy),t,n)}function TE(e,t,n,r){let a=r.includes(".")?aE(n,r):()=>n[r];if(Ct(e)){const i=t[e];Ve(i)&&$e(a,i)}else if(Ve(e))$e(a,e.bind(n));else if(pt(e))if(Fe(e))e.forEach(i=>TE(i,t,n,r));else{const i=Ve(e.handler)?e.handler.bind(n):t[e.handler];Ve(i)&&$e(a,i,e)}}function hE(e){const t=e.type,{mixins:n,extends:r}=t,{mixins:a,optionsCache:i,config:{optionMergeStrategies:o}}=e.appContext,s=i.get(t);let c;return s?c=s:!a.length&&!n&&!r?c=t:(c={},a.length&&a.forEach(l=>Pa(c,l,o,!0)),Pa(c,t,o)),pt(t)&&i.set(t,c),c}function Pa(e,t,n,r=!1){const{mixins:a,extends:i}=t;i&&Pa(e,i,n,!0),a&&a.forEach(o=>Pa(e,o,n,!0));for(const o in t)if(!(r&&o==="expose")){const s=Xf[o]||n&&n[o];e[o]=s?s(e[o],t[o]):t[o]}return e}const Xf={data:V_,props:z_,emits:z_,methods:Hr,computed:Hr,beforeCreate:qt,created:qt,beforeMount:qt,mounted:qt,beforeUpdate:qt,updated:qt,beforeDestroy:qt,beforeUnmount:qt,destroyed:qt,unmounted:qt,activated:qt,deactivated:qt,errorCaptured:qt,serverPrefetch:qt,components:Hr,directives:Hr,watch:Jf,provide:V_,inject:Zf};function V_(e,t){return t?e?function(){return Dt(Ve(e)?e.call(this,this):e,Ve(t)?t.call(this,this):t)}:t:e}function Zf(e,t){return Hr(Nc(e),Nc(t))}function Nc(e){if(Fe(e)){const t={};for(let n=0;nt==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${zt(t)}Modifiers`]||e[`${Xn(t)}Modifiers`];function nb(e,t,...n){if(e.isUnmounted)return;const r=e.vnode.props||bt;let a=n;const i=t.startsWith("update:"),o=i&&tb(r,t.slice(7));o&&(o.trim&&(a=n.map(_=>Ct(_)?_.trim():_)),o.number&&(a=n.map($c)));let s,c=r[s=Ca(t)]||r[s=Ca(zt(t))];!c&&i&&(c=r[s=Ca(Xn(t))]),c&&dn(c,e,6,a);const l=r[s+"Once"];if(l){if(!e.emitted)e.emitted={};else if(e.emitted[s])return;e.emitted[s]=!0,dn(l,e,6,a)}}const rb=new WeakMap;function RE(e,t,n=!1){const r=n?rb:t.emitsCache,a=r.get(e);if(a!==void 0)return a;const i=e.emits;let o={},s=!1;if(!Ve(e)){const c=l=>{const _=RE(l,t,!0);_&&(s=!0,Dt(o,_))};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}return!i&&!s?(pt(e)&&r.set(e,null),null):(Fe(i)?i.forEach(c=>o[c]=null):Dt(o,i),pt(e)&&r.set(e,o),o)}function si(e,t){return!e||!Wa(t)?!1:(t=t.slice(2).replace(/Once$/,""),dt(e,t[0].toLowerCase()+t.slice(1))||dt(e,Xn(t))||dt(e,t))}function W_(e){const{type:t,vnode:n,proxy:r,withProxy:a,propsOptions:[i],slots:o,attrs:s,emit:c,render:l,renderCache:_,props:d,data:u,setupState:m,ctx:p,inheritAttrs:E}=e,S=La(e);let b,h;try{if(n.shapeFlag&4){const D=a||r,L=D;b=hn(l.call(L,D,_,d,m,u,p)),h=s}else{const D=t;b=hn(D.length>1?D(d,{attrs:s,slots:o,emit:c}):D(d,null)),h=t.props?s:ab(s)}}catch(D){Zr.length=0,ni(D,e,1),b=ke(Bt)}let A=b;if(h&&E!==!1){const D=Object.keys(h),{shapeFlag:L}=A;D.length&&L&7&&(i&&D.some(Ka)&&(h=ib(h,i)),A=Qn(A,h,!1,!0))}return n.dirs&&(A=Qn(A,null,!1,!0),A.dirs=A.dirs?A.dirs.concat(n.dirs):n.dirs),n.transition&&ur(A,n.transition),b=A,La(S),b}const ab=e=>{let t;for(const n in e)(n==="class"||n==="style"||Wa(n))&&((t||(t={}))[n]=e[n]);return t},ib=(e,t)=>{const n={};for(const r in e)(!Ka(r)||!(r.slice(9)in t))&&(n[r]=e[r]);return n};function ob(e,t,n){const{props:r,children:a,component:i}=e,{props:o,children:s,patchFlag:c}=t,l=i.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&c>=0){if(c&1024)return!0;if(c&16)return r?K_(r,o,l):!!o;if(c&8){const _=t.dynamicProps;for(let d=0;d<_.length;d++){const u=_[d];if(CE(o,r,u)&&!si(l,u))return!0}}}else return(a||s)&&(!s||!s.$stable)?!0:r===o?!1:r?o?K_(r,o,l):!0:!!o;return!1}function K_(e,t,n){const r=Object.keys(t);if(r.length!==Object.keys(e).length)return!0;for(let a=0;aObject.create(NE),yE=e=>Object.getPrototypeOf(e)===NE;function lb(e,t,n,r=!1){const a={},i=OE();e.propsDefaults=Object.create(null),IE(e,t,a,i);for(const o in e.propsOptions[0])o in a||(a[o]=void 0);n?e.props=r?a:Kg(a):e.type.props?e.props=a:e.props=i,e.attrs=i}function cb(e,t,n,r){const{props:a,attrs:i,vnode:{patchFlag:o}}=e,s=at(a),[c]=e.propsOptions;let l=!1;if((r||o>0)&&!(o&16)){if(o&8){const _=e.vnode.dynamicProps;for(let d=0;d<_.length;d++){let u=_[d];if(si(e.emitsOptions,u))continue;const m=t[u];if(c)if(dt(i,u))m!==i[u]&&(i[u]=m,l=!0);else{const p=zt(u);a[p]=Oc(c,s,p,m,e,!1)}else m!==i[u]&&(i[u]=m,l=!0)}}}else{IE(e,t,a,i)&&(l=!0);let _;for(const d in s)(!t||!dt(t,d)&&((_=Xn(d))===d||!dt(t,_)))&&(c?n&&(n[d]!==void 0||n[_]!==void 0)&&(a[d]=Oc(c,s,d,void 0,e,!0)):delete a[d]);if(i!==s)for(const d in i)(!t||!dt(t,d))&&(delete i[d],l=!0)}l&&Ln(e.attrs,"set","")}function IE(e,t,n,r){const[a,i]=e.propsOptions;let o=!1,s;if(t)for(let c in t){if(zr(c))continue;const l=t[c];let _;a&&dt(a,_=zt(c))?!i||!i.includes(_)?n[_]=l:(s||(s={}))[_]=l:si(e.emitsOptions,c)||(!(c in r)||l!==r[c])&&(r[c]=l,o=!0)}if(i){const c=at(n),l=s||bt;for(let _=0;_{c=!0;const[u,m]=AE(d,t,!0);Dt(o,u),m&&s.push(...m)};!n&&t.mixins.length&&t.mixins.forEach(_),e.extends&&_(e.extends),e.mixins&&e.mixins.forEach(_)}if(!i&&!c)return pt(e)&&r.set(e,Cr),Cr;if(Fe(i))for(let _=0;_e==="_"||e==="_ctx"||e==="$stable",n_=e=>Fe(e)?e.map(hn):[hn(e)],db=(e,t,n)=>{if(t._n)return t;const r=Rt((...a)=>n_(t(...a)),n);return r._c=!1,r},DE=(e,t,n)=>{const r=e._ctx;for(const a in e){if(t_(a))continue;const i=e[a];if(Ve(i))t[a]=db(a,i,r);else if(i!=null){const o=n_(i);t[a]=()=>o}}},xE=(e,t)=>{const n=n_(t);e.slots.default=()=>n},ME=(e,t,n)=>{for(const r in t)(n||!t_(r))&&(e[r]=t[r])},ub=(e,t,n)=>{const r=e.slots=OE();if(e.vnode.shapeFlag&32){const a=t._;a?(ME(r,t,n),n&&Ig(r,"_",a,!0)):DE(t,r)}else t&&xE(e,t)},pb=(e,t,n)=>{const{vnode:r,slots:a}=e;let i=!0,o=bt;if(r.shapeFlag&32){const s=t._;s?n&&s===1?i=!1:ME(a,t,n):(i=!t.$stable,DE(t,a)),o=t}else t&&(xE(e,t),o={default:1});if(i)for(const s in a)!t_(s)&&o[s]==null&&delete a[s]},$t=fb;function mb(e){return gb(e)}function gb(e,t){const n=Ja();n.__VUE__=!0;const{insert:r,remove:a,patchProp:i,createElement:o,createText:s,createComment:c,setText:l,setElementText:_,parentNode:d,nextSibling:u,setScopeId:m=Nn,insertStaticContent:p}=e,E=(g,T,w,B=null,k=null,H=null,J=void 0,ee=null,te=!!T.dynamicChildren)=>{if(g===T)return;g&&!or(g,T)&&(B=F(g),ze(g,k,H,!0),g=null),T.patchFlag===-2&&(te=!1,T.dynamicChildren=null);const{type:Z,ref:fe,shapeFlag:oe}=T;switch(Z){case li:S(g,T,w,B);break;case Bt:b(g,T,w,B);break;case Oa:g==null&&h(T,w,B,J);break;case et:x(g,T,w,B,k,H,J,ee,te);break;default:oe&1?L(g,T,w,B,k,H,J,ee,te):oe&6?j(g,T,w,B,k,H,J,ee,te):(oe&64||oe&128)&&Z.process(g,T,w,B,k,H,J,ee,te,O)}fe!=null&&k?Qr(fe,g&&g.ref,H,T||g,!T):fe==null&&g&&g.ref!=null&&Qr(g.ref,null,H,g,!0)},S=(g,T,w,B)=>{if(g==null)r(T.el=s(T.children),w,B);else{const k=T.el=g.el;T.children!==g.children&&l(k,T.children)}},b=(g,T,w,B)=>{g==null?r(T.el=c(T.children||""),w,B):T.el=g.el},h=(g,T,w,B)=>{[g.el,g.anchor]=p(g.children,T,w,B,g.el,g.anchor)},A=({el:g,anchor:T},w,B)=>{let k;for(;g&&g!==T;)k=u(g),r(g,w,B),g=k;r(T,w,B)},D=({el:g,anchor:T})=>{let w;for(;g&&g!==T;)w=u(g),a(g),g=w;a(T)},L=(g,T,w,B,k,H,J,ee,te)=>{if(T.type==="svg"?J="svg":T.type==="math"&&(J="mathml"),g==null)y(T,w,B,k,H,J,ee,te);else{const Z=g.el&&g.el._isVueCE?g.el:null;try{Z&&Z._beginPatch(),C(g,T,k,H,J,ee,te)}finally{Z&&Z._endPatch()}}},y=(g,T,w,B,k,H,J,ee)=>{let te,Z;const{props:fe,shapeFlag:oe,transition:ne,dirs:be}=g;if(te=g.el=o(g.type,H,fe&&fe.is,fe),oe&8?_(te,g.children):oe&16&&v(g.children,te,null,B,k,yi(g,H),J,ee),be&&jn(g,null,B,"created"),I(te,g,g.scopeId,J,B),fe){for(const Be in fe)Be!=="value"&&!zr(Be)&&i(te,Be,null,fe[Be],H,B);"value"in fe&&i(te,"value",null,fe.value,H),(Z=fe.onVnodeBeforeMount)&&gn(Z,B,g)}be&&jn(g,null,B,"beforeMount");const De=Eb(k,ne);De&&ne.beforeEnter(te),r(te,T,w),((Z=fe&&fe.onVnodeMounted)||De||be)&&$t(()=>{try{Z&&gn(Z,B,g),De&&ne.enter(te),be&&jn(g,null,B,"mounted")}finally{}},k)},I=(g,T,w,B,k)=>{if(w&&m(g,w),B)for(let H=0;H{for(let Z=te;Z{const ee=T.el=g.el;let{patchFlag:te,dynamicChildren:Z,dirs:fe}=T;te|=g.patchFlag&16;const oe=g.props||bt,ne=T.props||bt;let be;if(w&&tr(w,!1),(be=ne.onVnodeBeforeUpdate)&&gn(be,w,T,g),fe&&jn(T,g,w,"beforeUpdate"),w&&tr(w,!0),(oe.innerHTML&&ne.innerHTML==null||oe.textContent&&ne.textContent==null)&&_(ee,""),Z?P(g.dynamicChildren,Z,ee,w,B,yi(T,k),H):J||Ne(g,T,ee,null,w,B,yi(T,k),H,!1),te>0){if(te&16)U(ee,oe,ne,w,k);else if(te&2&&oe.class!==ne.class&&i(ee,"class",null,ne.class,k),te&4&&i(ee,"style",oe.style,ne.style,k),te&8){const De=T.dynamicProps;for(let Be=0;Be{be&&gn(be,w,T,g),fe&&jn(T,g,w,"updated")},B)},P=(g,T,w,B,k,H,J)=>{for(let ee=0;ee{if(T!==w){if(T!==bt)for(const H in T)!zr(H)&&!(H in w)&&i(g,H,T[H],null,k,B);for(const H in w){if(zr(H))continue;const J=w[H],ee=T[H];J!==ee&&H!=="value"&&i(g,H,ee,J,k,B)}"value"in w&&i(g,"value",T.value,w.value,k)}},x=(g,T,w,B,k,H,J,ee,te)=>{const Z=T.el=g?g.el:s(""),fe=T.anchor=g?g.anchor:s("");let{patchFlag:oe,dynamicChildren:ne,slotScopeIds:be}=T;be&&(ee=ee?ee.concat(be):be),g==null?(r(Z,w,B),r(fe,w,B),v(T.children||[],w,fe,k,H,J,ee,te)):oe>0&&oe&64&&ne&&g.dynamicChildren&&g.dynamicChildren.length===ne.length?(P(g.dynamicChildren,ne,w,k,H,J,ee),(T.key!=null||k&&T===k.subTree)&&r_(g,T,!0)):Ne(g,T,w,fe,k,H,J,ee,te)},j=(g,T,w,B,k,H,J,ee,te)=>{T.slotScopeIds=ee,g==null?T.shapeFlag&512?k.ctx.activate(T,w,B,J,te):ie(T,w,B,k,H,J,te):he(g,T,te)},ie=(g,T,w,B,k,H,J)=>{const ee=g.component=Cb(g,B,k);if(ai(g)&&(ee.ctx.renderer=O),Nb(ee,!1,J),ee.asyncDep){if(k&&k.registerDep(ee,ae,J),!g.el){const te=ee.subTree=ke(Bt);b(null,te,T,w),g.placeholder=te.el}}else ae(ee,g,T,w,k,H,J)},he=(g,T,w)=>{const B=T.component=g.component;if(ob(g,T,w))if(B.asyncDep&&!B.asyncResolved){ue(B,T,w);return}else B.next=T,B.update();else T.el=g.el,B.vnode=T},ae=(g,T,w,B,k,H,J)=>{const ee=()=>{if(g.isMounted){let{next:oe,bu:ne,u:be,parent:De,vnode:Be}=g;{const Q=LE(g);if(Q){oe&&(oe.el=Be.el,ue(g,oe,J)),Q.asyncDep.then(()=>{$t(()=>{g.isUnmounted||Z()},k)});return}}let tt=oe,rt;tr(g,!1),oe?(oe.el=Be.el,ue(g,oe,J)):oe=Be,ne&&Na(ne),(rt=oe.props&&oe.props.onVnodeBeforeUpdate)&&gn(rt,De,oe,Be),tr(g,!0);const Je=W_(g),$=g.subTree;g.subTree=Je,E($,Je,d($.el),F($),g,k,H),oe.el=Je.el,tt===null&&sb(g,Je.el),be&&$t(be,k),(rt=oe.props&&oe.props.onVnodeUpdated)&&$t(()=>gn(rt,De,oe,Be),k)}else{let oe;const{el:ne,props:be}=T,{bm:De,m:Be,parent:tt,root:rt,type:Je}=g,$=yr(T);tr(g,!1),De&&Na(De),!$&&(oe=be&&be.onVnodeBeforeMount)&&gn(oe,tt,T),tr(g,!0);{rt.ce&&rt.ce._hasShadowRoot()&&rt.ce._injectChildStyle(Je,g.parent?g.parent.type:void 0);const Q=g.subTree=W_(g);E(null,Q,w,B,g,k,H),T.el=Q.el}if(Be&&$t(Be,k),!$&&(oe=be&&be.onVnodeMounted)){const Q=T;$t(()=>gn(oe,tt,Q),k)}(T.shapeFlag&256||tt&&yr(tt.vnode)&&tt.vnode.shapeFlag&256)&&g.a&&$t(g.a,k),g.isMounted=!0,T=w=B=null}};g.scope.on();const te=g.effect=new wg(ee);g.scope.off();const Z=g.update=te.run.bind(te),fe=g.job=te.runIfDirty.bind(te);fe.i=g,fe.id=g.uid,te.scheduler=()=>Jc(fe),tr(g,!0),Z()},ue=(g,T,w)=>{T.component=g;const B=g.vnode.props;g.vnode=T,g.next=null,cb(g,T.props,B,w),pb(g,T.children,w),Fn(),k_(g),Bn()},Ne=(g,T,w,B,k,H,J,ee,te=!1)=>{const Z=g&&g.children,fe=g?g.shapeFlag:0,oe=T.children,{patchFlag:ne,shapeFlag:be}=T;if(ne>0){if(ne&128){Le(Z,oe,w,B,k,H,J,ee,te);return}else if(ne&256){ve(Z,oe,w,B,k,H,J,ee,te);return}}be&8?(fe&16&&Qe(Z,k,H),oe!==Z&&_(w,oe)):fe&16?be&16?Le(Z,oe,w,B,k,H,J,ee,te):Qe(Z,k,H,!0):(fe&8&&_(w,""),be&16&&v(oe,w,B,k,H,J,ee,te))},ve=(g,T,w,B,k,H,J,ee,te)=>{g=g||Cr,T=T||Cr;const Z=g.length,fe=T.length,oe=Math.min(Z,fe);let ne;for(ne=0;nefe?Qe(g,k,H,!0,!1,oe):v(T,w,B,k,H,J,ee,te,oe)},Le=(g,T,w,B,k,H,J,ee,te)=>{let Z=0;const fe=T.length;let oe=g.length-1,ne=fe-1;for(;Z<=oe&&Z<=ne;){const be=g[Z],De=T[Z]=te?Mn(T[Z]):hn(T[Z]);if(or(be,De))E(be,De,w,null,k,H,J,ee,te);else break;Z++}for(;Z<=oe&&Z<=ne;){const be=g[oe],De=T[ne]=te?Mn(T[ne]):hn(T[ne]);if(or(be,De))E(be,De,w,null,k,H,J,ee,te);else break;oe--,ne--}if(Z>oe){if(Z<=ne){const be=ne+1,De=bene)for(;Z<=oe;)ze(g[Z],k,H,!0),Z++;else{const be=Z,De=Z,Be=new Map;for(Z=De;Z<=ne;Z++){const Te=T[Z]=te?Mn(T[Z]):hn(T[Z]);Te.key!=null&&Be.set(Te.key,Z)}let tt,rt=0;const Je=ne-De+1;let $=!1,Q=0;const le=new Array(Je);for(Z=0;Z=Je){ze(Te,k,H,!0);continue}let ye;if(Te.key!=null)ye=Be.get(Te.key);else for(tt=De;tt<=ne;tt++)if(le[tt-De]===0&&or(Te,T[tt])){ye=tt;break}ye===void 0?ze(Te,k,H,!0):(le[ye-De]=Z+1,ye>=Q?Q=ye:$=!0,E(Te,T[ye],w,null,k,H,J,ee,te),rt++)}const we=$?Sb(le):Cr;for(tt=we.length-1,Z=Je-1;Z>=0;Z--){const Te=De+Z,ye=T[Te],qe=T[Te+1],q=Te+1{const{el:H,type:J,transition:ee,children:te,shapeFlag:Z}=g;if(Z&6){Xe(g.component.subTree,T,w,B);return}if(Z&128){g.suspense.move(T,w,B);return}if(Z&64){J.move(g,T,w,O);return}if(J===et){r(H,T,w);for(let oe=0;oeee.enter(H),k);else{const{leave:oe,delayLeave:ne,afterLeave:be}=ee,De=()=>{g.ctx.isUnmounted?a(H):r(H,T,w)},Be=()=>{H._isLeaving&&H[bn](!0),oe(H,()=>{De(),be&&be()})};ne?ne(H,De,Be):Be()}else r(H,T,w)},ze=(g,T,w,B=!1,k=!1)=>{const{type:H,props:J,ref:ee,children:te,dynamicChildren:Z,shapeFlag:fe,patchFlag:oe,dirs:ne,cacheIndex:be,memo:De}=g;if(oe===-2&&(k=!1),ee!=null&&(Fn(),Qr(ee,null,w,g,!0),Bn()),be!=null&&(T.renderCache[be]=void 0),fe&256){T.ctx.deactivate(g);return}const Be=fe&1&&ne,tt=!yr(g);let rt;if(tt&&(rt=J&&J.onVnodeBeforeUnmount)&&gn(rt,T,g),fe&6)st(g.component,w,B);else{if(fe&128){g.suspense.unmount(w,B);return}Be&&jn(g,null,T,"beforeUnmount"),fe&64?g.type.remove(g,T,w,O,B):Z&&!Z.hasOnce&&(H!==et||oe>0&&oe&64)?Qe(Z,T,w,!1,!0):(H===et&&oe&384||!k&&fe&16)&&Qe(te,T,w),B&&Tt(g)}const Je=De!=null&&be==null;(tt&&(rt=J&&J.onVnodeUnmounted)||Be||Je)&&$t(()=>{rt&&gn(rt,T,g),Be&&jn(g,null,T,"unmounted"),Je&&(g.el=null)},w)},Tt=g=>{const{type:T,el:w,anchor:B,transition:k}=g;if(T===et){Et(w,B);return}if(T===Oa){D(g);return}const H=()=>{a(w),k&&!k.persisted&&k.afterLeave&&k.afterLeave()};if(g.shapeFlag&1&&k&&!k.persisted){const{leave:J,delayLeave:ee}=k,te=()=>J(w,H);ee?ee(g.el,H,te):te()}else H()},Et=(g,T)=>{let w;for(;g!==T;)w=u(g),a(g),g=w;a(T)},st=(g,T,w)=>{const{bum:B,scope:k,job:H,subTree:J,um:ee,m:te,a:Z}=g;X_(te),X_(Z),B&&Na(B),k.stop(),H&&(H.flags|=8,ze(J,g,T,w)),ee&&$t(ee,T),$t(()=>{g.isUnmounted=!0},T)},Qe=(g,T,w,B=!1,k=!1,H=0)=>{for(let J=H;J{if(g.shapeFlag&6)return F(g.component.subTree);if(g.shapeFlag&128)return g.suspense.next();const T=u(g.anchor||g.el),w=T&&T[iE];return w?u(w):T};let z=!1;const de=(g,T,w)=>{let B;g==null?T._vnode&&(ze(T._vnode,null,null,!0),B=T._vnode.component):E(T._vnode||null,g,T,null,null,null,w),T._vnode=g,z||(z=!0,k_(B),jg(),z=!1)},O={p:E,um:ze,m:Xe,r:Tt,mt:ie,mc:v,pc:Ne,pbc:P,n:F,o:e};return{render:de,hydrate:void 0,createApp:eb(de)}}function yi({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function tr({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function Eb(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function r_(e,t,n=!1){const r=e.children,a=t.children;if(Fe(r)&&Fe(a))for(let i=0;i>1,e[n[s]]0&&(t[r]=n[i-1]),n[i]=r)}}for(i=n.length,o=n[i-1];i-- >0;)n[i]=o,o=t[o];return n}function LE(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:LE(t)}function X_(e){if(e)for(let t=0;te.__isSuspense;function fb(e,t){t&&t.pendingBranch?Fe(e)?t.effects.push(...e):t.effects.push(e):If(e)}const et=Symbol.for("v-fgt"),li=Symbol.for("v-txt"),Bt=Symbol.for("v-cmt"),Oa=Symbol.for("v-stc"),Zr=[];let Xt=null;function M(e=!1){Zr.push(Xt=e?null:[])}function bb(){Zr.pop(),Xt=Zr[Zr.length-1]||null}let aa=1;function ka(e,t=!1){aa+=e,e<0&&Xt&&t&&(Xt.hasOnce=!0)}function kE(e){return e.dynamicChildren=aa>0?Xt||Cr:null,bb(),aa>0&&Xt&&Xt.push(e),e}function Y(e,t,n,r,a,i){return kE(R(e,t,n,r,a,i,!0))}function ut(e,t,n,r,a){return kE(ke(e,t,n,r,a,!0))}function ia(e){return e?e.__v_isVNode===!0:!1}function or(e,t){return e.type===t.type&&e.key===t.key}const UE=({key:e})=>e??null,ya=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?Ct(e)||Nt(e)||Ve(e)?{i:wt,r:e,k:t,f:!!n}:e:null);function R(e,t=null,n=null,r=0,a=null,i=e===et?0:1,o=!1,s=!1){const c={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&UE(t),ref:t&&ya(t),scopeId:tE,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:i,patchFlag:r,dynamicProps:a,dynamicChildren:null,appContext:null,ctx:wt};return s?(a_(c,n),i&128&&e.normalize(c)):n&&(c.shapeFlag|=Ct(n)?8:16),aa>0&&!o&&Xt&&(c.patchFlag>0||i&6)&&c.patchFlag!==32&&Xt.push(c),c}const ke=Tb;function Tb(e,t=null,n=null,r=0,a=null,i=!1){if((!e||e===SE)&&(e=Bt),ia(e)){const s=Qn(e,t,!0);return n&&a_(s,n),aa>0&&!i&&Xt&&(s.shapeFlag&6?Xt[Xt.indexOf(e)]=s:Xt.push(s)),s.patchFlag=-2,s}if(Db(e)&&(e=e.__vccOpts),t){t=FE(t);let{class:s,style:c}=t;s&&!Ct(s)&&(t.class=Ye(s)),pt(c)&&(ei(c)&&!Fe(c)&&(c=Dt({},c)),t.style=On(c))}const o=Ct(e)?1:PE(e)?128:oE(e)?64:pt(e)?4:Ve(e)?2:0;return R(e,t,n,r,a,o,i,!0)}function FE(e){return e?ei(e)||yE(e)?Dt({},e):e:null}function Qn(e,t,n=!1,r=!1){const{props:a,ref:i,patchFlag:o,children:s,transition:c}=e,l=t?Ua(a||{},t):a,_={__v_isVNode:!0,__v_skip:!0,type:e.type,props:l,key:l&&UE(l),ref:t&&t.ref?n&&i?Fe(i)?i.concat(ya(t)):[i,ya(t)]:ya(t):i,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:s,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==et?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:c,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Qn(e.ssContent),ssFallback:e.ssFallback&&Qn(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return c&&r&&ur(_,c.clone(_)),_}function At(e=" ",t=0){return ke(li,null,e,t)}function hb(e,t){const n=ke(Oa,null,e);return n.staticCount=t,n}function Re(e="",t=!1){return t?(M(),ut(Bt,null,e)):ke(Bt,null,e)}function hn(e){return e==null||typeof e=="boolean"?ke(Bt):Fe(e)?ke(et,null,e.slice()):ia(e)?Mn(e):ke(li,null,String(e))}function Mn(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Qn(e)}function a_(e,t){let n=0;const{shapeFlag:r}=e;if(t==null)t=null;else if(Fe(t))n=16;else if(typeof t=="object")if(r&65){const a=t.default;a&&(a._c&&(a._d=!1),a_(e,a()),a._c&&(a._d=!0));return}else{n=32;const a=t._;!a&&!yE(t)?t._ctx=wt:a===3&&wt&&(wt.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else Ve(t)?(t={default:t,_ctx:wt},n=32):(t=String(t),r&64?(n=16,t=[At(t)]):n=8);e.children=t,e.shapeFlag|=n}function Ua(...e){const t={};for(let n=0;nGt||wt;let Fa,yc;{const e=Ja(),t=(n,r)=>{let a;return(a=e[n])||(a=e[n]=[]),a.push(r),i=>{a.length>1?a.forEach(o=>o(i)):a[0](i)}};Fa=t("__VUE_INSTANCE_SETTERS__",n=>Gt=n),yc=t("__VUE_SSR_SETTERS__",n=>oa=n)}const da=e=>{const t=Gt;return Fa(e),e.scope.on(),()=>{e.scope.off(),Fa(t)}},Z_=()=>{Gt&&Gt.scope.off(),Fa(null)};function BE(e){return e.vnode.shapeFlag&4}let oa=!1;function Nb(e,t=!1,n=!1){t&&yc(t);const{props:r,children:a}=e.vnode,i=BE(e);lb(e,r,i,t),ub(e,a,n||t);const o=i?Ob(e,t):void 0;return t&&yc(!1),o}function Ob(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,Wf);const{setup:r}=n;if(r){Fn();const a=e.setupContext=r.length>1?Ib(e):null,i=da(e),o=_a(r,e,0,[e.props,a]),s=Ng(o);if(Bn(),i(),(s||e.sp)&&!yr(e)&&uE(e),s){if(o.then(Z_,Z_),t)return o.then(c=>{J_(e,c)}).catch(c=>{ni(c,e,0)});e.asyncDep=o}else J_(e,o)}else GE(e)}function J_(e,t,n){Ve(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:pt(t)&&(e.setupState=Xg(t)),GE(e)}function GE(e,t,n){const r=e.type;e.render||(e.render=r.render||Nn);{const a=da(e);Fn();try{Kf(e)}finally{Bn(),a()}}}const yb={get(e,t){return Ft(e,"get",""),e[t]}};function Ib(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.attrs,yb),slots:e.slots,emit:e.emit,expose:t}}function _i(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Xg(ti(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Xr)return Xr[n](e)},has(t,n){return n in t||n in Xr}})):e.proxy}function Ab(e,t=!0){return Ve(e)?e.displayName||e.name:e.name||t&&e.__name}function Db(e){return Ve(e)&&"__vccOpts"in e}const pe=(e,t)=>Rf(e,t,oa);function f(e,t,n){try{ka(-1);const r=arguments.length;return r===2?pt(t)&&!Fe(t)?ia(t)?ke(e,null,[t]):ke(e,t):ke(e,null,t):(r>3?n=Array.prototype.slice.call(arguments,2):r===3&&ia(n)&&(n=[n]),ke(e,t,n))}finally{ka(1)}}const xb="3.5.32";/**
-* @vue/runtime-dom v3.5.32
-* (c) 2018-present Yuxi (Evan) You and Vue contributors
-* @license MIT
-**/let Ic;const j_=typeof window<"u"&&window.trustedTypes;if(j_)try{Ic=j_.createPolicy("vue",{createHTML:e=>e})}catch{}const YE=Ic?e=>Ic.createHTML(e):e=>e,Mb="http://www.w3.org/2000/svg",Lb="http://www.w3.org/1998/Math/MathML",xn=typeof document<"u"?document:null,ed=xn&&xn.createElement("template"),wb={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,r)=>{const a=t==="svg"?xn.createElementNS(Mb,e):t==="mathml"?xn.createElementNS(Lb,e):n?xn.createElement(e,{is:n}):xn.createElement(e);return e==="select"&&r&&r.multiple!=null&&a.setAttribute("multiple",r.multiple),a},createText:e=>xn.createTextNode(e),createComment:e=>xn.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>xn.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,r,a,i){const o=n?n.previousSibling:t.lastChild;if(a&&(a===i||a.nextSibling))for(;t.insertBefore(a.cloneNode(!0),n),!(a===i||!(a=a.nextSibling)););else{ed.innerHTML=YE(r==="svg"?``:r==="mathml"?``:e);const s=ed.content;if(r==="svg"||r==="mathml"){const c=s.firstChild;for(;c.firstChild;)s.appendChild(c.firstChild);s.removeChild(c)}t.insertBefore(s,n)}return[o?o.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},Vn="transition",Gr="animation",Ar=Symbol("_vtc"),qE={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},$E=Dt({},lE,qE),Pb=e=>(e.displayName="Transition",e.props=$E,e),Ba=Pb((e,{slots:t})=>f(Uf,HE(e),t)),nr=(e,t=[])=>{Fe(e)?e.forEach(n=>n(...t)):e&&e(...t)},td=e=>e?Fe(e)?e.some(t=>t.length>1):e.length>1:!1;function HE(e){const t={};for(const x in e)x in qE||(t[x]=e[x]);if(e.css===!1)return t;const{name:n="v",type:r,duration:a,enterFromClass:i=`${n}-enter-from`,enterActiveClass:o=`${n}-enter-active`,enterToClass:s=`${n}-enter-to`,appearFromClass:c=i,appearActiveClass:l=o,appearToClass:_=s,leaveFromClass:d=`${n}-leave-from`,leaveActiveClass:u=`${n}-leave-active`,leaveToClass:m=`${n}-leave-to`}=e,p=kb(a),E=p&&p[0],S=p&&p[1],{onBeforeEnter:b,onEnter:h,onEnterCancelled:A,onLeave:D,onLeaveCancelled:L,onBeforeAppear:y=b,onAppear:I=h,onAppearCancelled:v=A}=t,C=(x,j,ie,he)=>{x._enterCancelled=he,zn(x,j?_:s),zn(x,j?l:o),ie&&ie()},P=(x,j)=>{x._isLeaving=!1,zn(x,d),zn(x,m),zn(x,u),j&&j()},U=x=>(j,ie)=>{const he=x?I:h,ae=()=>C(j,x,ie);nr(he,[j,ae]),nd(()=>{zn(j,x?c:i),En(j,x?_:s),td(he)||rd(j,r,E,ae)})};return Dt(t,{onBeforeEnter(x){nr(b,[x]),En(x,i),En(x,o)},onBeforeAppear(x){nr(y,[x]),En(x,c),En(x,l)},onEnter:U(!1),onAppear:U(!0),onLeave(x,j){x._isLeaving=!0;const ie=()=>P(x,j);En(x,d),x._enterCancelled?(En(x,u),Ac(x)):(Ac(x),En(x,u)),nd(()=>{x._isLeaving&&(zn(x,d),En(x,m),td(D)||rd(x,r,S,ie))}),nr(D,[x,ie])},onEnterCancelled(x){C(x,!1,void 0,!0),nr(A,[x])},onAppearCancelled(x){C(x,!0,void 0,!0),nr(v,[x])},onLeaveCancelled(x){P(x),nr(L,[x])}})}function kb(e){if(e==null)return null;if(pt(e))return[Ii(e.enter),Ii(e.leave)];{const t=Ii(e);return[t,t]}}function Ii(e){return YS(e)}function En(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[Ar]||(e[Ar]=new Set)).add(t)}function zn(e,t){t.split(/\s+/).forEach(r=>r&&e.classList.remove(r));const n=e[Ar];n&&(n.delete(t),n.size||(e[Ar]=void 0))}function nd(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let Ub=0;function rd(e,t,n,r){const a=e._endId=++Ub,i=()=>{a===e._endId&&r()};if(n!=null)return setTimeout(i,n);const{type:o,timeout:s,propCount:c}=VE(e,t);if(!o)return r();const l=o+"end";let _=0;const d=()=>{e.removeEventListener(l,u),i()},u=m=>{m.target===e&&++_>=c&&d()};setTimeout(()=>{_(n[p]||"").split(", "),a=r(`${Vn}Delay`),i=r(`${Vn}Duration`),o=ad(a,i),s=r(`${Gr}Delay`),c=r(`${Gr}Duration`),l=ad(s,c);let _=null,d=0,u=0;t===Vn?o>0&&(_=Vn,d=o,u=i.length):t===Gr?l>0&&(_=Gr,d=l,u=c.length):(d=Math.max(o,l),_=d>0?o>l?Vn:Gr:null,u=_?_===Vn?i.length:c.length:0);const m=_===Vn&&/\b(?:transform|all)(?:,|$)/.test(r(`${Vn}Property`).toString());return{type:_,timeout:d,propCount:u,hasTransform:m}}function ad(e,t){for(;e.lengthid(n)+id(e[r])))}function id(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function Ac(e){return(e?e.ownerDocument:document).body.offsetHeight}function Fb(e,t,n){const r=e[Ar];r&&(t=(t?[t,...r]:[...r]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const od=Symbol("_vod"),Bb=Symbol("_vsh"),Gb=Symbol(""),Yb=/(?:^|;)\s*display\s*:/;function qb(e,t,n){const r=e.style,a=Ct(n);let i=!1;if(n&&!a){if(t)if(Ct(t))for(const o of t.split(";")){const s=o.slice(0,o.indexOf(":")).trim();n[s]==null&&Ia(r,s,"")}else for(const o in t)n[o]==null&&Ia(r,o,"");for(const o in n)o==="display"&&(i=!0),Ia(r,o,n[o])}else if(a){if(t!==n){const o=r[Gb];o&&(n+=";"+o),r.cssText=n,i=Yb.test(n)}}else t&&e.removeAttribute("style");od in e&&(e[od]=i?r.display:"",e[Bb]&&(r.display="none"))}const sd=/\s*!important$/;function Ia(e,t,n){if(Fe(n))n.forEach(r=>Ia(e,t,r));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const r=$b(e,t);sd.test(n)?e.setProperty(Xn(r),n.replace(sd,""),"important"):e[r]=n}}const ld=["Webkit","Moz","ms"],Ai={};function $b(e,t){const n=Ai[t];if(n)return n;let r=zt(t);if(r!=="filter"&&r in e)return Ai[t]=r;r=Za(r);for(let a=0;aDi||(Wb.then(()=>Di=0),Di=Date.now());function Qb(e,t){const n=r=>{if(!r._vts)r._vts=Date.now();else if(r._vts<=n.attached)return;dn(Xb(r,n.value),t,5,[r])};return n.value=e,n.attached=Kb(),n}function Xb(e,t){if(Fe(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(r=>a=>!a._stopped&&r&&r(a))}else return t}const md=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Zb=(e,t,n,r,a,i)=>{const o=a==="svg";t==="class"?Fb(e,r,o):t==="style"?qb(e,n,r):Wa(t)?Ka(t)||Vb(e,t,n,r,i):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Jb(e,t,r,o))?(dd(e,t,r),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&_d(e,t,r,o,i,t!=="value")):e._isVueCE&&(jb(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!Ct(r)))?dd(e,zt(t),r,i,t):(t==="true-value"?e._trueValue=r:t==="false-value"&&(e._falseValue=r),_d(e,t,r,o))};function Jb(e,t,n,r){if(r)return!!(t==="innerHTML"||t==="textContent"||t in e&&md(t)&&Ve(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="autocorrect"||t==="sandbox"&&e.tagName==="IFRAME"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const a=e.tagName;if(a==="IMG"||a==="VIDEO"||a==="CANVAS"||a==="SOURCE")return!1}return md(t)&&Ct(n)?!1:t in e}function jb(e,t){const n=e._def.props;if(!n)return!1;const r=zt(t);return Array.isArray(n)?n.some(a=>zt(a)===r):Object.keys(n).some(a=>zt(a)===r)}const zE=new WeakMap,WE=new WeakMap,Ga=Symbol("_moveCb"),gd=Symbol("_enterCb"),eT=e=>(delete e.props.mode,e),tT=eT({name:"TransitionGroup",props:Dt({},$E,{tag:String,moveClass:String}),setup(e,{slots:t}){const n=ci(),r=sE();let a,i;return gE(()=>{if(!a.length)return;const o=e.moveClass||`${e.name||"v"}-move`;if(!oT(a[0].el,n.vnode.el,o)){a=[];return}a.forEach(rT),a.forEach(aT);const s=a.filter(iT);Ac(n.vnode.el),s.forEach(c=>{const l=c.el,_=l.style;En(l,o),_.transform=_.webkitTransform=_.transitionDuration="";const d=l[Ga]=u=>{u&&u.target!==l||(!u||u.propertyName.endsWith("transform"))&&(l.removeEventListener("transitionend",d),l[Ga]=null,zn(l,o))};l.addEventListener("transitionend",d)}),a=[]}),()=>{const o=at(e),s=HE(o);let c=o.tag||et;if(a=[],i)for(let l=0;l{s.split(/\s+/).forEach(c=>c&&r.classList.remove(c))}),n.split(/\s+/).forEach(s=>s&&r.classList.add(s)),r.style.display="none";const i=t.nodeType===1?t:t.parentNode;i.appendChild(r);const{hasTransform:o}=VE(r);return i.removeChild(r),o}const Ed=e=>{const t=e.props["onUpdate:modelValue"]||!1;return Fe(t)?n=>Na(t,n):t};function sT(e){e.target.composing=!0}function Sd(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const xi=Symbol("_assign");function fd(e,t,n){return t&&(e=e.trim()),n&&(e=$c(e)),e}const lT={created(e,{modifiers:{lazy:t,trim:n,number:r}},a){e[xi]=Ed(a);const i=r||a.props&&a.props.type==="number";hr(e,t?"change":"input",o=>{o.target.composing||e[xi](fd(e.value,n,i))}),(n||i)&&hr(e,"change",()=>{e.value=fd(e.value,n,i)}),t||(hr(e,"compositionstart",sT),hr(e,"compositionend",Sd),hr(e,"change",Sd))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:n,modifiers:{lazy:r,trim:a,number:i}},o){if(e[xi]=Ed(o),e.composing)return;const s=(i||e.type==="number")&&!/^0\d/.test(e.value)?$c(e.value):e.value,c=t??"";if(s===c)return;const l=e.getRootNode();(l instanceof Document||l instanceof ShadowRoot)&&l.activeElement===e&&e.type!=="range"&&(r&&t===n||a&&e.value.trim()===c)||(e.value=c)}},cT=["ctrl","shift","alt","meta"],_T={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>cT.some(n=>e[`${n}Key`]&&!t.includes(n))},sa=(e,t)=>{if(!e)return e;const n=e._withMods||(e._withMods={}),r=t.join(".");return n[r]||(n[r]=((a,...i)=>{for(let o=0;o{const n=e._withKeys||(e._withKeys={}),r=t.join(".");return n[r]||(n[r]=(a=>{if(!("key"in a))return;const i=Xn(a.key);if(t.some(o=>o===i||dT[o]===i))return e(a)}))},uT=Dt({patchProp:Zb},wb);let bd;function pT(){return bd||(bd=mb(uT))}const mT=((...e)=>{const t=pT().createApp(...e),{mount:n}=t;return t.mount=r=>{const a=ET(r);if(!a)return;const i=t._component;!Ve(i)&&!i.render&&!i.template&&(i.template=a.innerHTML),a.nodeType===1&&(a.textContent="");const o=n(a,!1,gT(a));return a instanceof Element&&(a.removeAttribute("v-cloak"),a.setAttribute("data-v-app","")),o},t});function gT(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function ET(e){return Ct(e)?document.querySelector(e):e}/*!
- * pinia v3.0.4
- * (c) 2025 Eduardo San Martin Morote
- * @license MIT
- */let QE;const di=e=>QE=e,XE=Symbol();function xc(e){return e&&typeof e=="object"&&Object.prototype.toString.call(e)==="[object Object]"&&typeof e.toJSON!="function"}var Jr;(function(e){e.direct="direct",e.patchObject="patch object",e.patchFunction="patch function"})(Jr||(Jr={}));function ST(){const e=Vc(!0),t=e.run(()=>X({}));let n=[],r=[];const a=ti({install(i){di(a),a._a=i,i.provide(XE,a),i.config.globalProperties.$pinia=a,r.forEach(o=>n.push(o)),r=[]},use(i){return this._a?n.push(i):r.push(i),this},_p:n,_a:null,_e:e,_s:new Map,state:t});return a}const ZE=()=>{};function Td(e,t,n,r=ZE){e.add(t);const a=()=>{e.delete(t)&&r()};return!n&&Lg()&&XS(a),a}function br(e,...t){e.forEach(n=>{n(...t)})}const fT=e=>e(),hd=Symbol(),Mi=Symbol();function Mc(e,t){e instanceof Map&&t instanceof Map?t.forEach((n,r)=>e.set(r,n)):e instanceof Set&&t instanceof Set&&t.forEach(e.add,e);for(const n in t){if(!t.hasOwnProperty(n))continue;const r=t[n],a=e[n];xc(a)&&xc(r)&&e.hasOwnProperty(n)&&!Nt(r)&&!Un(r)?e[n]=Mc(a,r):e[n]=r}return e}const bT=Symbol();function TT(e){return!xc(e)||!Object.prototype.hasOwnProperty.call(e,bT)}const{assign:Wn}=Object;function hT(e){return!!(Nt(e)&&e.effect)}function vT(e,t,n,r){const{state:a,actions:i,getters:o}=t,s=n.state.value[e];let c;function l(){s||(n.state.value[e]=a?a():{});const _=bf(n.state.value[e]);return Wn(_,i,Object.keys(o||{}).reduce((d,u)=>(d[u]=ti(pe(()=>{di(n);const m=n._s.get(e);return o[u].call(m,m)})),d),{}))}return c=JE(e,l,t,n,r,!0),c}function JE(e,t,n={},r,a,i){let o;const s=Wn({actions:{}},n),c={deep:!0};let l,_,d=new Set,u=new Set,m;const p=r.state.value[e];!i&&!p&&(r.state.value[e]={});let E;function S(v){let C;l=_=!1,typeof v=="function"?(v(r.state.value[e]),C={type:Jr.patchFunction,storeId:e,events:m}):(Mc(r.state.value[e],v),C={type:Jr.patchObject,payload:v,storeId:e,events:m});const P=E=Symbol();Lt().then(()=>{E===P&&(l=!0)}),_=!0,br(d,C,r.state.value[e])}const b=i?function(){const{state:C}=n,P=C?C():{};this.$patch(U=>{Wn(U,P)})}:ZE;function h(){o.stop(),d.clear(),u.clear(),r._s.delete(e)}const A=(v,C="")=>{if(hd in v)return v[Mi]=C,v;const P=function(){di(r);const U=Array.from(arguments),x=new Set,j=new Set;function ie(ue){x.add(ue)}function he(ue){j.add(ue)}br(u,{args:U,name:P[Mi],store:L,after:ie,onError:he});let ae;try{ae=v.apply(this&&this.$id===e?this:L,U)}catch(ue){throw br(j,ue),ue}return ae instanceof Promise?ae.then(ue=>(br(x,ue),ue)).catch(ue=>(br(j,ue),Promise.reject(ue))):(br(x,ae),ae)};return P[hd]=!0,P[Mi]=C,P},D={_p:r,$id:e,$onAction:Td.bind(null,u),$patch:S,$reset:b,$subscribe(v,C={}){const P=Td(d,v,C.detached,()=>U()),U=o.run(()=>$e(()=>r.state.value[e],x=>{(C.flush==="sync"?_:l)&&v({storeId:e,type:Jr.direct,events:m},x)},Wn({},c,C)));return P},$dispose:h},L=ca(D);r._s.set(e,L);const I=(r._a&&r._a.runWithContext||fT)(()=>r._e.run(()=>(o=Vc()).run(()=>t({action:A}))));for(const v in I){const C=I[v];if(Nt(C)&&!hT(C)||Un(C))i||(p&&TT(C)&&(Nt(C)?C.value=p[v]:Mc(C,p[v])),r.state.value[e][v]=C);else if(typeof C=="function"){const P=A(C,v);I[v]=P,s.actions[v]=C}}return Wn(L,I),Wn(at(L),I),Object.defineProperty(L,"$state",{get:()=>r.state.value[e],set:v=>{S(C=>{Wn(C,v)})}}),r._p.forEach(v=>{Wn(L,o.run(()=>v({store:L,app:r._a,pinia:r,options:s})))}),p&&i&&n.hydrate&&n.hydrate(L.$state,p),l=!0,_=!0,L}/*! #__NO_SIDE_EFFECTS__ */function ui(e,t,n){let r;const a=typeof t=="function";r=a?n:t;function i(o,s){const c=Af();return o=o||(c?cr(XE,null):null),o&&di(o),o=QE,o._s.has(e)||(a?JE(e,t,r,o):vT(e,r,o)),o._s.get(e)}return i.$id=e,i}const RT="modulepreload",CT=function(e){return"/"+e},vd={},NT=function(t,n,r){let a=Promise.resolve();if(n&&n.length>0){let o=function(l){return Promise.all(l.map(_=>Promise.resolve(_).then(d=>({status:"fulfilled",value:d}),d=>({status:"rejected",reason:d}))))};document.getElementsByTagName("link");const s=document.querySelector("meta[property=csp-nonce]"),c=(s==null?void 0:s.nonce)||(s==null?void 0:s.getAttribute("nonce"));a=o(n.map(l=>{if(l=CT(l),l in vd)return;vd[l]=!0;const _=l.endsWith(".css"),d=_?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${l}"]${d}`))return;const u=document.createElement("link");if(u.rel=_?"stylesheet":RT,_||(u.as="script"),u.crossOrigin="",u.href=l,c&&u.setAttribute("nonce",c),document.head.appendChild(u),_)return new Promise((m,p)=>{u.addEventListener("load",m),u.addEventListener("error",()=>p(new Error(`Unable to preload CSS for ${l}`)))})}))}function i(o){const s=new Event("vite:preloadError",{cancelable:!0});if(s.payload=o,window.dispatchEvent(s),!s.defaultPrevented)throw o}return a.then(o=>{for(const s of o||[])s.status==="rejected"&&i(s.reason);return t().catch(i)})},jE="";window.addEventListener("unhandledrejection",e=>{console.error("[API] Unhandled rejection:",e.reason)});async function kt(e,t,n){const r={method:e,headers:{},credentials:"include"};n!==void 0&&(r.headers["Content-Type"]="application/json",r.body=JSON.stringify(n));const a=await fetch(`${jE}${t}`,r);if(a.status===401){try{const{useAuthStore:o}=await NT(async()=>{const{useAuthStore:c}=await Promise.resolve().then(()=>YT);return{useAuthStore:c}},void 0),s=o();s.user=null}catch{}const i=await a.text().catch(()=>"");throw new Error(`${e} ${t} → 401: ${i}`)}if(!a.ok){const i=await a.text().catch(()=>"");throw new Error(`${e} ${t} → ${a.status}: ${i}`)}return a.status===204?null:a.json()}function OT(){return kt("GET","/auth/me")}function yT(){return kt("POST","/auth/logout")}function IT(){return kt("GET","/agents/profiles")}function Rd({limit:e=30,offset:t=0,profileId:n=null,search:r=null}={}){const a=new URLSearchParams({limit:String(e),offset:String(t)});return n&&a.set("profile_id",n),r&&a.set("search",r),kt("GET",`/sessions?${a.toString()}`)}function Cd(e){return kt("GET",`/sessions/${e}`)}function AT(e){return kt("POST","/sessions",{profile_id:e})}function DT(e){return kt("DELETE",`/sessions/${e}`)}function xT(e,t){return kt("PATCH",`/sessions/${e}/pin`,{pinned:t})}function MT(e){return kt("POST",`/sessions/${e}/stop`)}function LT(e){return kt("POST",`/sessions/${e}/generate-name`)}function wT(e){return kt("GET",`/sessions/${e}/content`)}function PT(e){return kt("GET",`/eval/feedback/${e}`)}function kT(e,t,n){return kt("POST","/eval/feedback",{session_id:e,message_index:t,rating:n})}function UT(e){return kt("GET",`/sessions/${e}/files`)}async function FT(e,t){const n=new FormData;n.append("file",t);const r=await fetch(`${jE}/sessions/${e}/files`,{method:"POST",credentials:"include",body:n});if(!r.ok){const a=await r.text().catch(()=>"");throw new Error(`Upload failed: ${r.status}: ${a}`)}return r.json()}function BT(e){return kt("GET",`/sessions/${e}/recall`)}function eS(e){return kt("DELETE",`/sessions/${e}/recall`)}function tS(e){return kt("POST",`/sessions/${e}/recall/skip`)}const Cn=ui("sessions",()=>{const t=X([]),n=X(!1),r=X(!1),a=X(!0),i=X(0),o=X(null),s=X(""),c=X(!1),l=X(null),_=X(!1);async function d(v=null){o.value=v,n.value=!0;try{const C=await Rd({limit:30,offset:0,profileId:c.value?null:v,search:c.value?s.value:null}),P=Array.isArray(C)?C:C.items;t.value=P,a.value=Array.isArray(C)?!1:C.has_more,i.value=Array.isArray(C)?P.length:C.next_offset,c.value&&(l.value={query:s.value,items:[...P],hasMore:a.value,nextOffset:i.value})}finally{n.value=!1}}async function u(){if(!(n.value||r.value||!a.value)){r.value=!0;try{const v=await Rd({limit:30,offset:i.value,profileId:c.value?null:o.value,search:c.value?s.value:null}),C=Array.isArray(v)?v:v.items,P=new Set(t.value.map(U=>U.session_id));t.value=[...t.value,...C.filter(U=>!P.has(U.session_id))],a.value=Array.isArray(v)?!1:v.has_more,i.value=Array.isArray(v)?t.value.length:v.next_offset,c.value&&(l.value={query:s.value,items:[...t.value],hasMore:a.value,nextOffset:i.value})}finally{r.value=!1}}}function m(v){s.value=v,c.value=v.length>0}function p(){s.value&&(c.value=!0,l.value&&l.value.query===s.value?(t.value=l.value.items,a.value=l.value.hasMore,i.value=l.value.nextOffset):d())}function E(){s.value="",c.value=!1,l.value=null}function S(){c.value=!1}async function b(v){const C=await AT(v);return t.value.unshift({session_id:C.session_id,profile_id:C.profile_id,created_at:C.created_at,last_active:C.created_at,message_count:0,preview:"",pinned:!1}),i.value+=1,C}async function h(v){await DT(v),t.value=t.value.filter(C=>C.session_id!==v),i.value=Math.max(0,i.value-1)}async function A(v,C){await xT(v,C);const P=t.value.map(U=>U.session_id===v?{...U,pinned:C}:U);P.sort((U,x)=>(x.pinned?1:0)-(U.pinned?1:0)),t.value=P}function D(v,C){const P=t.value.find(U=>U.session_id===v);P&&(P.has_pending_recall=C)}function L(v,C){const P=t.value.find(U=>U.session_id===v);P&&(P.preview=C)}function y(v,C){const P=t.value.find(U=>U.session_id===v);P&&(P.name=C)}const I=pe(()=>_.value?t.value.filter(v=>v.has_pending_recall):t.value);return{sessions:t,filteredSessions:I,loading:n,loadingMore:r,hasMore:a,currentProfileId:o,searchQuery:s,searchActive:c,hasPendingRecallFilter:_,fetchSessions:d,fetchMoreSessions:u,createSession:b,deleteSession:h,pinSession:A,updatePreview:L,updateName:y,updateRecallStatus:D,setSearch:m,restoreSearch:p,clearSearch:E,exitSearch:S,searchCache:l}}),ua=ui("profiles",()=>{const e=X([]),t=X(null),n=X(!1);async function r(){n.value=!0;try{e.value=await IT(),e.value.length&&!t.value&&(t.value=e.value[0].id)}finally{n.value=!1}}function a(i){return e.value.find(o=>o.id===i)??null}return{profiles:e,selectedProfileId:t,loading:n,fetchProfiles:r,getProfile:a}});let Nd=null;async function GT(e){try{const t=Cn(),n=t.sessions.find(a=>a.session_id===e);if(n!=null&&n.name)return;const{name:r}=await LT(e);r&&t.updateName(e,r)}catch{}}const Qt=ui("chat",()=>{const e=X(null),t=X(null),n=X([]),r=X(!1),a=X([]),i=X([]),o=X([]),s=X([]),c=X(0),l=X(0),_=X(!1),d=Rr(null),u=X(!1),m=X(null),p=X(null);async function E(O,G=null){if(!(e.value===O&&G==null)){Nd=O,_.value=!0,n.value=[],o.value=[],s.value=[],r.value=!1,d.value=null,c.value=0,l.value=0,m.value=G;try{const g=await Cd(O);if(Nd!==O)return;t.value=g.profile_id??null,n.value=de(g.messages??[]),await h(O),await A(O),await D(O),g.context_token_count&&(c.value=g.context_token_count),g.max_context_tokens&&(l.value=g.max_context_tokens),e.value=O,location.hash=O}catch(g){console.error("[chat] loadSession failed",g)}finally{_.value=!1}}}function S(){e.value=null,t.value=null,n.value=[],o.value=[],s.value=[],r.value=!1,d.value=null,c.value=0,l.value=0,location.hash=""}async function b(O){if(O)try{const G=await Cd(O);t.value=G.profile_id??null;const g=de(G.messages??[]);if(d.value&&!g.find(T=>T.id===d.value.id)){const T=g.slice().reverse().find(w=>w.role==="assistant");(!T||T.text!==d.value.text)&&g.push(d.value)}n.value=g,await h(O),await A(O),await D(O),G.context_token_count&&(c.value=G.context_token_count),G.max_context_tokens&&(l.value=G.max_context_tokens),d.value||(d.value=null,r.value=!1)}catch{}}async function h(O){var G,g;try{const{feedback:T=[]}=await PT(O);if(!T.length)return;const w=new Map(T.map(B=>[B.message_index,B.rating]));for(const B of n.value){if(B.role!=="assistant")continue;const k=(g=(G=B.id)==null?void 0:G.startsWith)!=null&&g.call(G,"h_")?Number(B.id.slice(2)):NaN;Number.isInteger(k)&&w.has(k)&&(B.rating=w.get(k))}}catch{}}async function A(O=e.value){if(!O){o.value=[];return}try{const{content:G=[]}=await wT(O);o.value=G}catch{o.value=[]}}async function D(O=e.value){if(!O){s.value=[];return}try{const{files:G=[]}=await UT(O);s.value=G}catch{s.value=[]}}function L(O){if(!(O!=null&&O.filename))return;const G=O.id||O.filename,g=o.value.findIndex(w=>(w.id||w.filename)===G),T={...O};g===-1?o.value.unshift(T):o.value.splice(g,1,{...o.value[g],...T})}async function y(O,G){var B,k;if(!e.value||!O)return;const g=(k=(B=O.id)==null?void 0:B.startsWith)!=null&&k.call(B,"h_")?Number(O.id.slice(2)):NaN;if(!Number.isInteger(g))return;const T=O.rating===G?0:G,w=O.rating??0;O.rating=T;try{await kT(e.value,g,T)}catch(H){throw O.rating=w,H}}function I(O){e.value&&(O?localStorage.setItem(`draft:${e.value}`,O):localStorage.removeItem(`draft:${e.value}`))}function v(O){return localStorage.getItem(`draft:${O}`)??""}function C(){if(d.value){const G=n.value.indexOf(d.value);G!==-1&&n.value.splice(G,1),d.value=null}r.value=!0;const O={id:`stream_${Date.now()}`,role:"assistant",type:"stream",thinking:null,tools:[],text:"",done:!1,time:new Date().toISOString(),animate:!u.value,statusLabel:null};n.value.push(O),d.value=n.value[n.value.length-1]}function P(){u.value=!0}function U(){u.value=!1,d.value&&(d.value.animate=!0)}function x(O){const G=d.value;G&&(G.thinking||(G.thinking={text:"",done:!1}),G.thinking.text+=O)}function j(){const O=d.value;O!=null&&O.thinking&&(O.thinking.done=!0)}function ie(O){for(let G=O.tools.length-1;G>=0;G--){const g=O.tools[G];if(g.kind==="tool"&&g.name==="spawn_agent")return g}}function he(O){const G=d.value;if(!G)return;const g={kind:"turn_thinking",isSubagent:O.is_subagent??!1,thinking:{text:O.thinking??"",done:!0}};if(O.is_subagent){const T=ie(G);if(T){T.steps.push(g);return}}G.tools.push(g)}function ae(O){const G=d.value;if(G){if(O.is_subagent){const g=ie(G);g&&(g.planningLabel=O.label??"");return}G.statusLabel=O.label??""}}function ue(O){const G=d.value;if(G){if(O.is_subagent){const g=ie(G);g&&(g.planningLabel=null,g.steps.push({kind:"plan",text:O.plan??""}));return}G.statusLabel=null,G.tools.push({kind:"plan",text:O.plan??""})}}function Ne(O){const G=d.value;if(!G)return;const g={kind:"tool",id:`tool_${Date.now()}`,name:O.tool,args:O.args,result:null,success:null,pending:!0,startedAt:Date.now(),isSubagent:O.is_subagent??!1,steps:[]};if(O.is_subagent){const T=ie(G);if(T){T.steps.push(g);return}}G.tools.push(g)}function ve(O){var T,w;const G=d.value;if(!G)return;if(O.is_subagent){const B=ie(G);if(B){let k=null;for(let H=B.steps.length-1;H>=0;H--){const J=B.steps[H];if(J.kind==="tool"&&J.name===O.tool&&J.pending){k=J;break}}if(k){k.result=O.result,k.success=O.success!==!1,k.pending=!1;return}}}let g=null;for(let B=G.tools.length-1;B>=0;B--){const k=G.tools[B];if(k.kind==="tool"&&k.name===O.tool&&k.pending){g=k;break}}if(g){if(g.result=O.result,g.success=O.success!==!1,g.pending=!1,O.metadata&&(g.metadata=O.metadata),O.tool==="content_publish"&&g.success&&O.metadata&&L(O.metadata),O.tool==="filesystem"&&g.success&&e.value){const B=typeof g.args=="object"?(T=g.args)==null?void 0:T.action:null;["write","edit","append","mkdir","rm","cp","mv"].includes(B)&&D(e.value),["write","edit"].includes(B)&&A(e.value)}if((O.tool==="terminal"||O.tool==="code_exec")&&g.success&&e.value&&D(e.value),O.tool==="schedule_recall"&&g.success&&e.value&&(Qe(e.value),Cn().updateRecallStatus(e.value,!0)),O.tool==="manage_recall"&&g.success&&e.value){const B=(w=g.args)==null?void 0:w.action;B==="cancel"?(p.value=null,Cn().updateRecallStatus(e.value,!1)):B==="skip"&&Qe(e.value)}}}function Le(O){const G=d.value;G&&(G.statusLabel&&(G.statusLabel=null),G.text+=O)}function Xe(O){const G=d.value;if(G){G.done=!0,G.elapsed_seconds=(O==null?void 0:O.elapsed_seconds)??null,G.tool_call_count=(O==null?void 0:O.tool_call_count)??null,G.token_count=(O==null?void 0:O.token_count)??null;const g=n.value.filter(T=>T.role==="assistant").length-1;G.id=`h_${g}`,d.value=null,!G.thinking&&!G.tools.length&&!G.text&&(n.value=n.value.filter(T=>T!==G))}r.value=!1,(O==null?void 0:O.context_tokens)!=null&&(c.value=O.context_tokens),(O==null?void 0:O.max_context_tokens)!=null&&(l.value=O.max_context_tokens),e.value&&(G!=null&&G.text)&&Cn().updatePreview(e.value,G.text.slice(0,80)),e.value&>(e.value)}function ze(){const O=d.value;if(O){O.done=!0;const G=n.value.filter(g=>g.role==="assistant").length-1;O.id=`h_${G}`,d.value=null,!O.thinking&&!O.tools.length&&!O.text&&(n.value=n.value.filter(g=>g!==O))}r.value=!1}function Tt(O){t.value=O.profile_id}function Et(O){(O==null?void 0:O.context_tokens)!=null&&(c.value=O.context_tokens),(O==null?void 0:O.max_context_tokens)!=null&&(l.value=O.max_context_tokens),n.value.push({id:`compress_${Date.now()}`,role:"system",type:"compression_notice",before:O.messages_before,after:O.messages_after,summary:O.summary??""})}function st(O){r.value=!1,d.value=null,n.value.push({id:`err_${Date.now()}`,role:"system",type:"error",text:O.message??"An error occurred"})}async function Qe(O=e.value){if(!O){p.value=null;return}try{const G=await BT(O);G&&G.id?p.value=G:p.value=null}catch{p.value=null}}function F(O){if(!O.session_id)return;const G=Cn(),g=O.status==="pending";G.updateRecallStatus(O.session_id,g),O.session_id===e.value&&(g?Qe(O.session_id):p.value=null)}function z(O,G,g){n.value.push({id:`user_${Date.now()}`,role:"user",text:O,images:[...G],files:[...g],time:new Date().toISOString(),animate:!0})}function de(O){var w,B;const G=[];let g=0,T=0;for(;gtypeof J=="string"&&J.startsWith("data:")?J:`data:image/jpeg;base64,${String(J??"")}`);G.push({id:`h_${g}`,role:"user",text:k.content??"",images:H,files:k.files??[],time:k.created_at??null,rawIndices:[g],isRecall:k.is_recall??!1}),g++;continue}if(k.role==="assistant"){const H=g,J=[];let ee=null,te="",Z=null;for(;g=O.length||O[g].role!=="assistant")break}}if(ee||J.length||te){const fe=`h_${T++}`;let oe=null,ne=null,be=null;for(let De=H;DeH+Be)})}continue}g++}return G}return{currentId:e,currentProfileId:t,messages:n,streaming:r,pendingImages:a,pendingFiles:i,artifacts:o,files:s,contextTokens:c,maxContextTokens:l,loading:_,streamingMsg:d,scrollToMessageIndex:m,recall:p,loadSession:E,clearSession:S,reloadSession:b,fetchArtifacts:A,fetchFiles:D,rateMessage:y,saveDraft:I,loadDraft:v,appendUserMessage:z,buildMessageList:de,onStreamStart:C,onReplayStart:P,onReplayEnd:U,onThinkingDelta:x,onThinkingEnd:j,onTurnThinking:he,onPlanningStatus:ae,onPlanReady:ue,onToolStarted:Ne,onToolCall:ve,onStreamDelta:Le,onStreamEnd:Xe,onStreamStopped:ze,onProfileSwitched:Tt,onContextCompressed:Et,onError:st,loadRecall:Qe,onRecallUpdate:F}}),i_=ui("auth",()=>{const e=X(null),t=X(!1),n=X(!1),r=pe(()=>e.value!==null),a=pe(()=>{var _;return((_=e.value)==null?void 0:_.role)==="admin"});function i(_){return e.value?e.value.role==="admin"?!0:(e.value.permissions||[]).includes(_):!1}async function o(){var _;console.log("[auth] fetchMe start"),t.value=!0;try{e.value=await OT(),console.log("[auth] fetchMe success",e.value)}catch(d){throw console.log("[auth] fetchMe error",d.message),(_=d.message)!=null&&_.includes("401")&&(e.value=null),d}finally{t.value=!1,console.log("[auth] fetchMe loading=false")}}async function s(){console.log("[auth] fetchStatus start");try{const _=await fetch("/auth/status");if(console.log("[auth] fetchStatus response",_.status,_.ok),_.ok){const d=await _.json();console.log("[auth] fetchStatus data",d),n.value=!!d.configured,console.log("[auth] fetchStatus authConfigured set to",n.value)}else console.log("[auth] fetchStatus not ok"),n.value=!1}catch(_){console.log("[auth] fetchStatus error",_),n.value=!1}}function c(){const _=navigator.userAgent.includes("NaviAndroid"),d=new URLSearchParams;_&&d.set("platform","android");const u=d.toString();window.location.href="/auth/login"+(u?"?"+u:"")}async function l(){try{await yT()}catch{}e.value=null,window.location.reload()}return{user:e,loading:t,authConfigured:n,isAuthenticated:r,isAdmin:a,hasPermission:i,fetchMe:o,fetchStatus:s,login:c,logout:l}}),YT=Object.freeze(Object.defineProperty({__proto__:null,useAuthStore:i_},Symbol.toStringTag,{value:"Module"})),o_="/images/logo.svg";function qT(e){return{all:e=e||new Map,on:function(t,n){var r=e.get(t);r&&r.push(n)||e.set(t,[n])},off:function(t,n){var r=e.get(t);r&&r.splice(r.indexOf(n)>>>0,1)},emit:function(t,n){(e.get(t)||[]).slice().map(function(r){r(n)}),(e.get("*")||[]).slice().map(function(r){r(t,n)})}}}function s_(e,t,n){if(!n)return t;const r=e==null?void 0:e[n];if(r==null)throw new Error(`Key is ${r} on item (keyField is '${n}')`);return r}function sr(e,t){return e.map((n,r)=>s_(n,r,t))}function $T(e,t,n){const r=[],a=[];for(let i=0;i0?c:null)}return{keys:r,sizes:a}}function HT(e,t,n){if(!e||e.keys.length!==t.length||e.sizes.length!==t.length)return!1;for(let r=0;r0&&(r[e.keys[a]]=i)}return r}function nS(e,t){if(!e.length||t.length<=e.length)return 0;const n=e[0],r=t.indexOf(n);if(r<=0||r+e.lengtht.length-r)return 0;for(let a=0;a=n&&c<=s?null:e{}:n.onVscrollUpdate(S),d=pe(()=>{const x=ge(e);if(n.vscrollData.simpleArray){if(x.index==null)throw new Error("index is required when using simple-array mode with dynamic item measurement");return x.index}if(n.vscrollData.keyField in x.item)return x.item[n.vscrollData.keyField];throw new Error(`keyField '${n.vscrollData.keyField}' not found in your item. You should set a valid keyField prop on your Scroller`)}),u=pe(()=>n.vscrollData.sizes[d.value]||0),m=pe(()=>ge(e).active&&n.vscrollData.active);function p(){m.value?i!==d.value&&(i=d.value,a=null,o=null,D(d.value)):a=d.value}function E(){ge(e).watchData&&!n.resizeObserver?c=$e(()=>ge(e).item,()=>{b()},{deep:!0}):c&&(c(),c=null)}function S({force:x}){!m.value&&x&&(o=d.value),(a===d.value||x||!u.value)&&p()}function b(){p()}function h(x){n.undefinedMap[x]&&n.undefinedSizeCount.value--,n.undefinedMap[x]=void 0}function A(x,j){if(n.vscrollData.sizes[x]){h(x);return}if(j){n.undefinedMap[x]||n.undefinedSizeCount.value++,n.undefinedMap[x]=!0;return}n.undefinedMap[x]&&(n.undefinedSizeCount.value--,n.undefinedMap[x]=!1)}function D(x){Lt(()=>{if(d.value===x){const j=ge(t);if(!j)return;const ie=j.offsetWidth,he=j.offsetHeight;L(ie,he)}i=null})}function L(x,j){const ie=~~(n.direction.value==="vertical"?j:x);ie&&u.value!==ie&&y(ie)}function y(x){var j,ie;h(d.value),n.vscrollData.sizes[d.value]=x,ge(e).emitResize&&((ie=(j=ge(r))==null?void 0:j.onResize)==null||ie.call(j,d.value))}function I(){if(!n.resizeObserver||s)return;const x=ge(t);x&&(n.resizeObserver.observe(x),x.$_vs_id=d.value,x.$_vs_onResize=C,s=!0)}function v(){if(!n.resizeObserver||!s)return;const x=ge(t);x&&(n.resizeObserver.unobserve(x),x.$_vs_onResize=void 0,s=!1)}function C(x,j,ie){d.value===x&&L(j,ie)}l.push($e(()=>ge(e).watchData,()=>{E()})),n.resizeObserver||l.push($e(()=>ge(e).sizeDependencies,()=>{b()},{deep:!0})),l.push($e(d,(x,j)=>{const ie=ge(t);ie&&(ie.$_vs_id=x),h(j),A(x,m.value);const he=n.vscrollData.sizes[x];if(!he){a=x,b();return}h(x),s&&(n.vscrollData.sizes[x]=he)})),l.push($e(m,x=>{A(d.value,x),n.resizeObserver?x?I():v():x&&o===d.value&&p()})),E();function P(){m.value&&(p(),I())}function U(){_(),v(),h(d.value);const x=ge(t);x&&(x.$_vs_id=void 0,x.$_vs_onResize=void 0),c&&(c(),c=null);for(const j of l)j();l.length=0}return{id:d,size:u,finalActive:m,updateSize:p,mount:P,unmount:U}}const VT={itemsLimit:1e3};function aS(e){return typeof window<"u"&&e===window}const zT=(()=>{if(typeof document>"u")return"negative";const e=document.createElement("div"),t=document.createElement("div");e.style.width="4px",e.style.height="1px",e.style.overflow="auto",e.style.direction="rtl",t.style.width="8px",t.style.height="1px",e.appendChild(t),document.body.appendChild(e),e.scrollLeft=-1;const n=e.scrollLeft<0;return document.body.removeChild(e),n?"negative":"default"})();function vr(e,t,n){return t!=="horizontal"||!n||aS(n)||getComputedStyle(n).direction!=="rtl"?e:zT==="negative"?-e:e}function WT(e,t,n){return vr(e,t,n)}function Li(e,t,n,r){const a=WT(n,t,e),i=!!(r!=null&&r.smooth);if(aS(e)){t==="vertical"?e.scrollTo({top:a,behavior:i?"smooth":"auto"}):e.scrollTo({left:a,behavior:i?"smooth":"auto"});return}if(typeof e.scrollTo=="function"){e.scrollTo(t==="vertical"?{top:a,behavior:i?"smooth":"auto"}:{left:a,behavior:i?"smooth":"auto"});return}t==="vertical"?e.scrollTop=a:e.scrollLeft=a}function KT(e,t,n){return n?t==="vertical"?window.innerHeight:window.innerWidth:t==="vertical"?e.clientHeight:e.clientWidth}const QT=/auto|scroll/;function iS(e,t){return e.parentNode===null?t:iS(e.parentNode,[...t,e])}function wi(e,t){return getComputedStyle(e,null).getPropertyValue(t)}function XT(e){return wi(e,"overflow")+wi(e,"overflow-y")+wi(e,"overflow-x")}function ZT(e){return QT.test(XT(e))}function ha(e){if(!(e instanceof HTMLElement||e instanceof SVGElement))return;const t=iS(e.parentNode,[]);for(let n=0;n{const $=ge(e);return $.items.length>0&&typeof $.items[0]!="object"}),j=pe(()=>{const $=ge(e);if($.itemSize===null){const Q={[-1]:{accumulator:0}},le=$.items,we=$.sizeField??"size",Te=$.minItemSize,ye=U.value;let qe=1e4,q=0,W;for(let _e=0,Ee=le.length;_ei.value.filter($=>$.nr.used).sort(($,Q)=>$.nr.index-Q.nr.index)),he=pe(()=>{const $=ge(e),Q=x.value?null:$.keyField;return $T($.items,Q,(le,we,Te)=>$.itemSize!=null?$.itemSize:U.value[Te]||(le==null?void 0:le[$.sizeField??"size"])||void 0)});function ae($){const Q=ge(e);return U.value=Lc($,Q.items,x.value?null:Q.keyField),Object.keys(U.value).length>0}function ue($){let Q=d.get($);return Q||(Q=[],d.set($,Q)),Q}function Ne($,Q,le,we,Te){const ye=ti({id:jT++,index:Q,used:!0,key:we,type:Te}),qe=Kg({item:le,position:0,offset:0,nr:ye,_vs_styleStamp:0});return $.push(qe),qe}function ve($){const Q=ue($);if(Q&&Q.length){const le=Q.pop();return le.nr.used=!0,Pi(le),le}}function Le($){const Q=$.nr.type;ue(Q).push($),$.nr.used=!1,$.position=-9999,Pi($),_.delete($.nr.key)}function Xe(){_.clear(),d.clear();for(let $=0,Q=i.value.length;${P.delete(Q),$()}),P.add(Q),Q}function Tt(){for(const $ of P)cancelAnimationFrame($);P.clear()}function Et(){S&&(clearTimeout(S),S=null),b&&(clearTimeout(b),b=null),h&&(clearTimeout(h),h=null),I&&(clearTimeout(I),I=null),v&&(clearTimeout(v),v=null)}function st(){var $;($=a==null?void 0:a.onResize)==null||$.call(a),s.value&&ne(!1)}function Qe(){y&&!C&&B();const $=ge(e);if(!u){if(u=!0,S)return;const Q=()=>ze(()=>{u=!1;const{continuous:le}=ne(!1,!0);le||(b&&clearTimeout(b),b=setTimeout(Qe,$.updateInterval+100))});Q(),$.updateInterval&&(S=setTimeout(()=>{S=null,u&&Q()},$.updateInterval))}}function F($,Q){var le,we;s.value&&($||Q.boundingClientRect.width!==0||Q.boundingClientRect.height!==0?((le=a==null?void 0:a.onVisible)==null||le.call(a),ze(()=>{ne(!1)})):(we=a==null?void 0:a.onHidden)==null||we.call(a))}function z(){const $=ge(t),Q=$?ha($):void 0;return window.document&&(Q===window.document.documentElement||Q===window.document.body)?window:Q||window}function de(){const $=ge(n);return $?ge(e).direction==="vertical"?$.scrollHeight:$.scrollWidth:0}function O(){const $=ge(t);if(!$)return{start:0,end:0};const Q=ge(e),le=Q.direction==="vertical";let we;if(Q.pageMode){const Te=$.getBoundingClientRect(),ye=le?Te.height:Te.width;let qe=-(le?Te.top:Te.left),q=le?window.innerHeight:window.innerWidth;qe<0&&(q+=qe,qe=0),qe+q>ye&&(q=ye-qe),we={start:qe,end:qe+q}}else le?we={start:$.scrollTop,end:$.scrollTop+$.clientHeight}:we={start:vr($.scrollLeft,Q.direction,$),end:vr($.scrollLeft,Q.direction,$)+$.clientWidth};return we}function G(){const $=ge(t);if(!$)return{start:0,end:0};if(ge(e).direction==="vertical"){const Q=vr($.scrollLeft,"horizontal",$);return{start:Q,end:Q+$.clientWidth}}return{start:$.scrollTop,end:$.scrollTop+$.clientHeight}}function g($){const Q=ge(e);if(Q.itemSize!=null)return Q.itemSize;const le=j.value[$];return(le==null?void 0:le.size)||Number(Q.minItemSize)||0}function T($){var Q;const le=ge(e),we=le.gridItems||1;return $<=0?0:le.itemSize!=null?Math.floor($/we)*le.itemSize:((Q=j.value[$-1])==null?void 0:Q.accumulator)||0}function w($){const Q=ge(e),le=Q.items.length,we=Q.gridItems||1;if(!le)return 0;if(Q.itemSize!=null){const q=Math.floor($/Q.itemSize)*we;return Math.min(Math.max(q,0),le-1)}let Te=0,ye=le-1,qe=0;for(;Te<=ye;){const q=Math.floor((Te+ye)/2);T(q)<=$?(qe=q,Te=q+1):ye=q-1}return qe}function B(){I&&(clearTimeout(I),I=null),y=null}function k(){I&&clearTimeout(I),I=setTimeout(()=>{y=null,I=null},150)}function H($,Q){if(!$.length){B();return}const le=Math.max(O().start-de(),0),we=Math.min(w(le),$.length-1),Te=$[we],ye=Q?Te==null?void 0:Te[Q]:we;if(ye==null){B();return}const qe=de()+T(we);y={key:ye,offset:O().start-qe}}function J($){if(!y)return!1;const Q=ge(e),le=$??Q.items,we=x.value?null:Q.keyField,Te=sr(le,we).indexOf(y.key);if(Te===-1)return B(),!1;const ye=de()+T(Te)+y.offset,qe=O().start;return Math.abs(ye-qe)<.5?!1:(C=!0,rt(ye),ze(()=>{C=!1}),!0)}function ee(){ge(e).pageMode?te():Z()}function te(){D=z(),D.addEventListener("scroll",Qe,JT()?{passive:!0}:!1),D.addEventListener("resize",st)}function Z(){D&&(D.removeEventListener("scroll",Qe),D.removeEventListener("resize",st),D=null)}function fe($,Q,le,we,Te,ye){const qe=Math.ceil($/Q)*le,q=Math.max(0,Math.floor(Te.start/le)),W=Math.min(Math.ceil(Te.end/le),Math.ceil($/Q)),_e=Math.max(0,Math.floor(ye.start/we)),Ee=Math.min(Math.ceil(ye.end/we),Q),Ze=[];for(let V=q;V=$)break;Ze.push(it)}}const Ue=Ze[0]??0,N=Ze.at(-1)??-1;return{renderedIndices:Ze,startIndex:Ue,endIndex:N+1,visibleStartIndex:Ue,visibleEndIndex:N,totalSize:qe}}function oe(){const $=ge(e);if(!$.gridItems||$.itemSize==null)return!1;const Q=ge(t);if(!Q)return!1;const le=$.itemSecondarySize||$.itemSize,we=$.direction==="vertical"?Q.clientWidth:Q.clientHeight;return le*$.gridItems>we}function ne($,Q=!1){var le,we;const Te=ge(e),ye=Te.itemSize,qe=Te.gridItems||1,q=Te.itemSecondarySize||ye,W=A,_e=Te.typeField,Ee=x.value?null:Te.keyField,Ze=Te.items,Ue=Ze.length,N=j.value,V=_,re=i.value;let Ie=null,it=null,We,ce,Se,Ae,_t;if(!Ue)We=ce=Ae=_t=Se=0;else if(E)We=Ae=0,ce=_t=Math.min(Te.prerender,Ze.length),Se=0;else{const je=O(),yt=G();if(Q){let Ot=je.start-m;Ot<0&&(Ot=-Ot);let pn=yt.start-p;pn<0&&(pn=-pn);const Zn=ye===null&&Ot>=W||ye!==null&&Ot>=ye,vt=qe>1&&ye!=null&&pn>=q;if(!Zn&&!vt)return{continuous:!0}}m=je.start,p=yt.start;const tn=Te.buffer;je.start-=tn,je.end+=tn,yt.start-=tn,yt.end+=tn;let sn=0;const $n=ge(n);$n&&(sn=$n.scrollHeight,je.start-=sn);const Hn=ge(r);if(Hn){const Ot=Hn.scrollHeight;je.end+=Ot}if(ye===null){let Ot,pn=0,Zn=Ue-1,vt=~~(Ue/2),Sr;do Sr=vt,Ot=N[vt].accumulator,Otje.start&&(Zn=vt),vt=~~((pn+Zn)/2);while(vt!==Sr);for(vt<0&&(vt=0),We=vt,Se=N[Ue-1].accumulator,ce=vt;ceUe&&(ce=Ue)),Ae=We;Ae1){const Ot=fe(Ue,qe,ye,q,je,yt);Ie=Ot.renderedIndices,it=new Set(Ie),We=Ot.startIndex,ce=Ot.endIndex,Ae=Ot.visibleStartIndex,_t=Ot.visibleEndIndex,Se=Ot.totalSize}else{We=~~(je.start/ye*qe);const Ot=We%qe;We-=Ot,ce=Math.ceil(je.end/ye*qe),Ae=Math.max(0,Math.floor((je.start-sn)/ye*qe)),_t=Math.floor((je.end-sn)/ye*qe),We<0&&(We=0),ce>Ue&&(ce=Ue),Ae<0&&(Ae=0),_t>Ue&&(_t=Ue),Se=Math.ceil(Ue/qe)*ye}}ce-We>VT.itemsLimit&&be(),o.value=Se;let Ge;const yn=We<=l&&ce>=c;if(!yn||$)Xe();else for(let je=0,yt=re.length;je=We&&Ge.nr.indexWe+yt);for(const je of ma){if(!(ye||N[je]&&N[je].size))continue;en=Ze[je];const yt=Ee?en[Ee]:je;if(yt==null)throw new Error(`Key is ${yt} on item (keyField is '${Ee}')`);if(Ge=V.get(yt),Ge)Ge.item!==en&&(Ge.item=en),Ge.nr.used||console.warn(`Expected existing view's used flag to be true, got ${Ge.nr.used}`);else{if(In=en[_e],Ge=ve(In),Ge){const tn=Ge.nr.index!==je||Ge.nr.key!==yt;Ge.item=en,Ge.nr.index=je,Ge.nr.key=yt,Ge.nr.type!==In&&console.warn("Reused view's type does not match pool's type"),tn&&Pi(Ge)}else Ge=Ne(re,je,en,yt,In);V.set(yt,Ge)}ye===null?(Ge.position=((le=N[je-1])==null?void 0:le.accumulator)||0,Ge.offset=0):(Ge.position=Math.floor(je/qe)*ye,Ge.offset=je%qe*q)}return c=We,l=ce,Te.emitUpdate&&((we=a==null?void 0:a.onUpdate)==null||we.call(a,We,ce,Ae,_t)),h&&clearTimeout(h),h=setTimeout(Be,Te.updateInterval+300),{continuous:yn}}function be(){throw v=setTimeout(()=>{v=null,console.warn("It seems the scroller element isn't scrolling, so it tries to render all the items at once.","Scroller:",ge(t)),console.warn("Make sure the scroller has a fixed height (or width) and 'overflow-y' (or 'overflow-x') set to 'auto' so it can scroll correctly and only render the items visible in the scroll viewport.")}),new Error("Rendered items limit reached")}function De(){if(oe())return!1;const $=i.value.filter(({nr:Q})=>Q.used);for(let Q=1;Q<$.length;Q++)if($[Q].nr.index!==$[Q-1].nr.index+1)return!0;return!1}function Be(){i.value.sort(($,Q)=>$.nr.index-Q.nr.index),De()&&(ne(!1),h&&clearTimeout(h))}function tt($,Q){const le=ge(e),we=ge(t);if(!we)return;const Te=Math.max(0,Math.min($,le.items.length-1)),ye=O().start,qe=KT(we,le.direction,le.pageMode),q=T(Te),W=g(Te),_e=Od(q,W,ye,qe,Q==null?void 0:Q.align,(Q==null?void 0:Q.offset)??0);if(_e!=null&&(rt(_e,Q),le.gridItems&&le.itemSize!=null)){const Ee=ge(t);if(!Ee)return;const Ze=le.gridItems,Ue=le.itemSecondarySize||le.itemSize,N=Te%Ze*Ue,V=le.direction==="vertical"?"horizontal":"vertical",re=V==="horizontal"?vr(Ee.scrollLeft,"horizontal",Ee):Ee.scrollTop,Ie=V==="horizontal"?Ee.clientWidth:Ee.clientHeight,it=Od(N,Ue,re,Ie,Q==null?void 0:Q.align,(Q==null?void 0:Q.offset)??0);it!=null&&Li(Ee,V,it,Q)}}function rt($,Q){const le=ge(e),we=ge(t);if(we)if(le.pageMode){const Te=ha(we),ye=Te.getBoundingClientRect(),qe=we.getBoundingClientRect(),q=le.direction==="vertical"?"top":"left",W=ha(we)===document.documentElement||ha(we)===document.body?le.direction==="vertical"?window.scrollY:window.scrollX:vr(le.direction==="vertical"?Te.scrollTop:Te.scrollLeft,le.direction,Te),_e=qe[q]-ye[q];Li(Te.tagName==="HTML"?window:Te,le.direction,$+W+_e,Q)}else Li(we,le.direction,$,Q)}const Je=ge(e);return L=sr(Je.items,Je.items.length>0&&typeof Je.items[0]!="object"?null:Je.keyField),Je.cache&&ae(Je.cache),Je.prerender&&(E=!0,ne(!1)),Je.gridItems&&!Je.itemSize&&console.error("[vue-recycle-scroller] You must provide an itemSize when using gridItems"),un(()=>{ee(),Lt(()=>{E=!1,ne(!0),s.value=!0})}),e_(()=>{const $=m;typeof $=="number"&&Lt(()=>{rt($)})}),Kt(()=>{Et(),Tt(),Z()}),$e(()=>ge(e).cache,$=>{ae($),ne(!0)}),$e(()=>ge(e).items,($,Q)=>{const le=ge(e),we=x.value?null:le.keyField,Te=sr($,we);if(le.shift){const ye=Q?sr(Q,we):L;nS(ye,Te)>0?H(Q??[],we):B()}else B();L=Te,J($),ne(!0)}),$e(()=>ge(e).pageMode,()=>{ee(),ne(!1)}),$e(j,()=>{J()&&k(),ne(!1)},{deep:!0}),$e(()=>ge(e).gridItems,()=>{ne(!0)}),$e(()=>ge(e).itemSecondarySize,()=>{ne(!0)}),{pool:i,visiblePool:ie,totalSize:o,ready:s,sizes:j,simpleArray:x,scrollToItem:tt,scrollToPosition:rt,getScroll:O,findItemIndex:w,getItemOffset:T,getItemSize:g,cacheSnapshot:he,restoreCache:ae,updateVisibleItems:ne,handleScroll:Qe,handleResize:st,handleVisibilityChange:F,sortViews:Be}}function Pc(e){return e.item}function th(e){return e._vs_styleStamp??0}const sS=["position","top","left","transform","willChange","visibility","pointerEvents"];function yd(e){const t={};for(const n of sS)t[n]=e.style[n];return t}function lS(e,t){for(const n of sS)e.style[n]=t[n]??""}function Id(e,t,n,r){if(!("view"in t)){lS(e,r);return}const a=n==="vertical",i=e.tagName==="TR",o=a?`translateY(${t.view.position}px) translateX(${t.view.offset}px)`:`translateX(${t.view.position}px) translateY(${t.view.offset}px)`;e.style.position="absolute",e.style.top=a&&i?`${t.view.position}px`:"0px",e.style.left=!a&&i?`${t.view.position}px`:"0px",e.style.transform=i?"":o,e.style.willChange=i?"unset":"transform",e.style.visibility=t.view.nr.used?"visible":"hidden",e.style.pointerEvents=t.view.nr.used?"":"none"}function Ad(e){return"view"in e?{item:Pc(e.view).item,active:e.view.nr.used,index:e.view.nr.index,watchData:e.watchData??!1,emitResize:e.emitResize??!1,sizeDependencies:e.sizeDependencies??null,onResize:e.onResize}:{watchData:!1,emitResize:!1,sizeDependencies:null,...e}}function Dd(e,t,n,r){return n?r??null:(e==null?void 0:e[t])??null}function nh(e){let t=0,n={};const r=qT();let a=!1,i,o=!1,s=[],c=null,l=null;const _=new Set,d=ca({active:!0,sizes:{},keyField:ge(e).keyField,simpleArray:!1}),u=pe(()=>ge(e).direction),m=pe(()=>ge(ge(e).el)),p=pe(()=>ge(ge(e).before)),E=pe(()=>ge(ge(e).after)),S=new Map;function b(F){let z=-1;return z=requestAnimationFrame(()=>{_.delete(z),F()}),_.add(z),z}function h(){for(const F of _)cancelAnimationFrame(F);_.clear()}typeof ResizeObserver<"u"&&(i=new ResizeObserver(F=>{b(()=>{if(Array.isArray(F)){for(const z of F)if(z.target&&z.target.$_vs_onResize){let de,O;if(z.borderBoxSize){const G=z.borderBoxSize[0];de=G.inlineSize,O=G.blockSize}else de=z.contentRect.width,O=z.contentRect.height;z.target.$_vs_onResize(z.target.$_vs_id,de,O)}}})}));const A={vscrollData:d,resizeObserver:i,direction:u,undefinedMap:n,undefinedSizeCount:{get value(){return t},set value(F){t=F}},onVscrollUpdate(F){const z=de=>{F(de)};return r.on("vscroll:update",z),()=>r.off("vscroll:update",z)}};ar("vscrollData",d),ar("vscrollParent",{get $_undefinedSizes(){return t},set $_undefinedSizes(F){t=F},get $_undefinedMap(){return n},set $_undefinedMap(F){n=F},$_events:r,direction:u}),ar("vscrollResizeObserver",i),ar("vscrollMeasurementContext",A),ar("vscrollAnchorRegistry",{delete(F){S.delete(F)},set(F,z){S.set(F,z)}});const D=pe(()=>{const F=ge(e);return F.items.length>0&&typeof F.items[0]!="object"}),L=pe(()=>{const F=[],z=ge(e),{items:de,keyField:O}=z,G=D.value,g=d.sizes,T=de.length;for(let w=0;w"u"&&!n[k]&&(H=0),F.push({item:B,id:k,size:H})}return F}),y=ge(e);s=sr(y.items,D.value?null:y.keyField),y.cache&&(d.sizes=Lc(y.cache,y.items,D.value?null:y.keyField));const I=pe(()=>{const F=ge(e);return{items:L.value,keyField:"id",direction:F.direction,itemSize:null,gridItems:void 0,itemSecondarySize:void 0,minItemSize:F.minItemSize,sizeField:"size",typeField:"type",buffer:F.buffer??200,pageMode:F.pageMode??!1,shift:!1,cache:F.cache,prerender:F.prerender??0,emitUpdate:F.emitUpdate??!1,updateInterval:F.updateInterval??0}});function v(){var F,z;Xe(),(z=(F=ge(e)).onResize)==null||z.call(F)}function C(){var F,z;r.emit("vscroll:update",{force:!1}),(z=(F=ge(e)).onVisible)==null||z.call(F)}const P=oS(I,m,p,E,{onResize:v,onVisible:C,onHidden:()=>{var F,z;return(z=(F=ge(e)).onHidden)==null?void 0:z.call(F)},onUpdate:(F,z,de,O)=>{var G,g;return(g=(G=ge(e)).onUpdate)==null?void 0:g.call(G,F,z,de,O)}}),U=new WeakMap;function x(){l!=null&&(cancelAnimationFrame(l),_.delete(l),l=null)}function j(){x(),c=null}function ie(){c==null||l!=null||(l=b(()=>{l=null,Ne()}))}function he(){const F=m.value;if(!F)return null;const z=F.getBoundingClientRect();let de=null;for(const[O,G]of S.entries()){if(!G.active||getComputedStyle(O).visibility==="hidden")continue;const g=O.getBoundingClientRect();if(g.bottom<=z.top||g.top>=z.bottom)continue;const T=Math.max(g.top,z.top)-z.top;(!de||T{o=!1}),!0)}function Ne(){const F=c,z=m.value;if(!F||!z)return;const de=L.value.findIndex(T=>T.id===F.logicalKey);if(de===-1){j();return}let O=!1;const G=P.getItemOffset(de)+F.logicalOffset;if(O=ue(G)||O,F.visualKey!=null)for(const[T,w]of S.entries()){if(!w.active||w.id!==F.visualKey||getComputedStyle(T).visibility==="hidden")continue;const B=T.getBoundingClientRect().top-z.getBoundingClientRect().top-F.visualOffset;O=ue(z.scrollTop+B)||O;break}let g=!0;for(const T of F.pendingKeys)if(!(typeof d.sizes[T]=="number"&&d.sizes[T]>0)){g=!1;break}if(!O&&g){if(F.stableFrames++,F.stableFrames>=2){j();return}}else F.stableFrames=0;ie()}function ve(F,z,de,O){const G=Vc(),g=Rr(z),T=Rr(de),w=Rr({onResize:de.onResize}),B=Rr(F),k=G.run(()=>($e(()=>{const H=g.value;if(!("view"in H))return{active:T.value.active,direction:u.value,id:Dd(T.value.item,ge(e).keyField,d.simpleArray,T.value.index),legacy:!0};const{view:J}=H;return{active:J.nr.used,direction:u.value,id:Pc(J).id,legacy:!1,position:J.position,offset:J.offset,styleStamp:th(J)}},()=>{const H=B.value;if(H){const J=g.value,ee="view"in J?Pc(J.view).id:Dd(T.value.item,ge(e).keyField,d.simpleArray,T.value.index);ee!=null&&S.set(H,{active:T.value.active&&d.active,id:ee}),Id(H,g.value,u.value,O)}},{immediate:!0}),rS(T,B,A,w)));k.mount(),U.set(F,{binding:g,scope:G,options:T,callbacks:w,el:B,controller:k,restoreStyles:O})}const Le={mounted(F,z){const de=yd(F);ve(F,z.value,Ad(z.value),de)},updated(F,z){const de=U.get(F),O=Ad(z.value);if(!de){const G=yd(F);ve(F,z.value,O,G);return}de.binding.value=z.value,de.options.value=O,de.callbacks.value={onResize:O.onResize},de.el.value=F,Id(F,z.value,u.value,de.restoreStyles)},unmounted(F){const z=U.get(F);z&&(z.controller.unmount(),z.scope.stop(),lS(F,z.restoreStyles),S.delete(F),U.delete(F))}};function Xe(F=!1){(F||D.value)&&(d.sizes={}),r.emit("vscroll:update",{force:!0})}function ze(F,z){P.scrollToItem(F,z)}function Tt(F){const z=ge(e);return d.sizes=Lc(F,z.items,D.value?null:z.keyField),P.restoreCache(F)}function Et(F,z){const de=ge(e),O=D.value?z??de.items.indexOf(F):F[de.keyField];return d.sizes[O]||0}function st(){const F=m.value;F&&(a||(a=!0,Lt(()=>{F.scrollTop=F.scrollHeight+5e3;const z=()=>{F.scrollTop=F.scrollHeight+5e3,b(()=>{F.scrollTop=F.scrollHeight+5e3,t===0?a=!1:b(z)})};b(z)})))}function Qe(){c&&!o&&j()}return $e(()=>ge(e).items,(F,z)=>{const de=ge(e),O=D.value?null:de.keyField,G=sr(F,O);if(de.shift){const g=z?sr(z,O):s,T=nS(g,G);T>0?(ae(g),c&&(c.pendingKeys=new Set(G.slice(0,T)),c.stableFrames=0,Lt(()=>{c&&Ne()}))):j()}else j();s=G,Xe()},{flush:"sync"}),$e(()=>ge(e).cache,F=>{F&&Tt(F)}),$e(D,F=>{d.simpleArray=F},{immediate:!0}),$e(()=>ge(e).direction,()=>{j(),Xe(!0)}),$e(m,(F,z)=>{z==null||z.removeEventListener("scroll",Qe),F==null||F.addEventListener("scroll",Qe)},{immediate:!0}),$e(L,(F,z)=>{const de=m.value;if(!de)return;if(c){Ne();return}const O=de.scrollTop,G=ge(e);let g=0,T=0;const w=Math.min(F.length,z.length);for(let k=0;k=O);k++)g+=z[k].size||G.minItemSize,T+=F[k].size||G.minItemSize;const B=T-g;B!==0&&(de.scrollTop+=B)},{flush:"post"}),e_(()=>{d.active=!0}),pE(()=>{d.active=!1}),gr(()=>{var F;x(),h(),(F=m.value)==null||F.removeEventListener("scroll",Qe),r.all.clear()}),{vscrollData:d,itemsWithSize:L,resizeObserver:i,measurementContext:A,vDynamicScrollerItem:Le,...P,simpleArray:D,forceUpdate:Xe,scrollToItem:ze,restoreCache:Tt,getItemSize:Et,scrollToBottom:st,onScrollerResize:v,onScrollerVisible:C}}const l_=new WeakMap;function rh(e){return typeof e=="function"?{callback:e,observer:null,intersection:void 0,visible:null}:{callback:e.callback,observer:null,intersection:e.intersection,visible:null}}function xd(e,t){cS(e);const n=rh(t.value);if(l_.set(e,n),typeof IntersectionObserver>"u"){const r=e.getBoundingClientRect();n.visible=!0,n.callback(!0,{boundingClientRect:r});return}n.observer=new IntersectionObserver(r=>{const a=r[0],i=!!(a!=null&&a.isIntersecting);n.visible!==null&&n.visible===i||(n.visible=i,n.callback(i,a))},n.intersection),n.observer.observe(e)}function cS(e){const t=l_.get(e);t!=null&&t.observer&&(t.observer.disconnect(),t.observer=null)}const ah={mounted(e,t){xd(e,t)},updated(e,t){t.value!==t.oldValue&&xd(e,t)},unmounted(e){cS(e),l_.delete(e)}},ih=Me({__name:"ItemView",props:{view:{},itemTag:{}},setup(e){const t=e;return(n,r)=>(M(),ut(oi(t.itemTag),{class:"vue-recycle-scroller__item-view"},{default:Rt(()=>[Rn(n.$slots,"default",{item:t.view.item,index:t.view.nr.index,active:t.view.nr.used})]),_:3}))}}),oh=Me({__name:"ResizeObserver",emits:["notify"],setup(e,{emit:t}){const n=t,r=X();let a=null,i=null;function o(){n("notify")}return un(()=>{var s;const c=(s=r.value)==null?void 0:s.parentElement;if(c){if(typeof ResizeObserver<"u"){a=new ResizeObserver(()=>{o()}),a.observe(c);return}i=()=>o(),window.addEventListener("resize",i)}}),Kt(()=>{a&&(a.disconnect(),a=null),i&&(window.removeEventListener("resize",i),i=null)}),(s,c)=>(M(),Y("div",{ref_key:"el",ref:r,class:"vue-recycle-scroller__resize-observer","aria-hidden":"true"},null,512))}}),sh=(e,t)=>{const n=e.__vccOpts||e;for(const[r,a]of t)n[r]=a;return n},lh=sh(oh,[["__scopeId","data-v-08cc04ab"]]),ch=Me({__name:"RecycleScroller",props:{items:{},keyField:{default:"id"},direction:{default:"vertical"},listTag:{default:"div"},itemTag:{default:"div"},itemSize:{default:null},gridItems:{default:void 0},itemSecondarySize:{default:void 0},minItemSize:{default:null},sizeField:{default:"size"},typeField:{default:"type"},buffer:{default:200},pageMode:{type:Boolean,default:!1},shift:{type:Boolean,default:!1},cache:{default:void 0},prerender:{default:0},emitUpdate:{type:Boolean,default:!1},disableTransform:{type:Boolean,default:!1},updateInterval:{default:0},skipHover:{type:Boolean,default:!1},listClass:{default:""},itemClass:{default:""}},emits:["resize","visible","hidden","update","scrollStart","scrollEnd"],setup(e,{expose:t,emit:n}){const r=e,a=n,i=ah,o=X(),s=X(),c=X(),l=X(null),_=oS(r,o,s,c,{onResize:()=>a("resize"),onVisible:()=>a("visible"),onHidden:()=>a("hidden"),onUpdate:(ie,he,ae,ue)=>{a("update",ie,he,ae,ue),ae<=0&&a("scrollStart"),ue>=r.items.length-1&&a("scrollEnd")}}),{pool:d,visiblePool:u,totalSize:m,ready:p,scrollToItem:E,scrollToPosition:S,getScroll:b,findItemIndex:h,getItemOffset:A,getItemSize:D,cacheSnapshot:L,restoreCache:y,updateVisibleItems:I,handleScroll:v,handleResize:C,handleVisibilityChange:P}=_;function U(ie){l.value=ie}function x(){l.value=null}const j=pe(()=>{const ie={[r.direction==="vertical"?"minHeight":"minWidth"]:`${m.value}px`};if(r.gridItems&&r.itemSize!=null){const he=(r.itemSecondarySize||r.itemSize)*r.gridItems;ie[r.direction==="vertical"?"minWidth":"minHeight"]=`${he}px`}return ie});return t({el:o,visiblePool:u,scrollToItem:E,scrollToPosition:S,getScroll:b,findItemIndex:h,getItemOffset:A,getItemSize:D,cacheSnapshot:L,restoreCache:y,updateVisibleItems:I}),(ie,he)=>nE((M(),Y("div",{ref_key:"el",ref:o,class:Ye(["vue-recycle-scroller",{"grid-mode":r.gridItems,ready:K(p),"page-mode":r.pageMode,[`direction-${r.direction}`]:!0}]),onScrollPassive:he[0]||(he[0]=(...ae)=>K(v)&&K(v)(...ae))},[ie.$slots.before?(M(),Y("div",{key:0,ref_key:"before",ref:s,class:"vue-recycle-scroller__slot"},[Rn(ie.$slots,"before")],512)):Re("",!0),(M(),ut(oi(r.listTag),{style:On(j.value),class:Ye(["vue-recycle-scroller__item-wrapper",r.listClass])},{default:Rt(()=>[(M(!0),Y(et,null,Jt(K(d),ae=>(M(),ut(ih,Ua({key:ae.nr.id,view:ae,"item-tag":r.itemTag,style:K(p)?[r.disableTransform?{[r.direction==="vertical"?"top":"left"]:`${ae.position}px`,willChange:"unset"}:{transform:`translate${r.direction==="vertical"?"Y":"X"}(${ae.position}px) translate${r.direction==="vertical"?"X":"Y"}(${ae.offset}px)`},{width:r.gridItems?`${r.direction==="vertical"&&r.itemSecondarySize||r.itemSize}px`:void 0,height:r.gridItems?`${r.direction==="horizontal"&&r.itemSecondarySize||r.itemSize}px`:void 0,visibility:ae.nr.used?"visible":"hidden"}]:null,class:["vue-recycle-scroller__item-view",[r.itemClass,{hover:!r.skipHover&&l.value===ae.nr.key}]]},zf(r.skipHover?{}:{mouseenter:()=>{U(ae.nr.key)},mouseleave:()=>{x()}})),{default:Rt(ue=>[Rn(ie.$slots,"default",Ua({ref_for:!0},ue))]),_:2},1040,["view","item-tag","style","class"]))),128)),r.items.length===0?Rn(ie.$slots,"empty",{key:0}):Re("",!0)]),_:3},8,["style","class"])),ie.$slots.after?(M(),Y("div",{key:1,ref_key:"after",ref:c,class:"vue-recycle-scroller__slot"},[Rn(ie.$slots,"after")],512)):Re("",!0),ke(lh,{onNotify:K(C)},null,8,["onNotify"])],34)),[[K(i),K(P)]])}}),_h=Me({inheritAttrs:!1,__name:"DynamicScroller",props:{items:{},keyField:{default:"id"},direction:{default:"vertical"},listTag:{default:"div"},itemTag:{default:"div"},minItemSize:{},shift:{type:Boolean,default:!1},cache:{default:void 0}},emits:["resize","visible"],setup(e,{expose:t,emit:n}){const r=e,a=n,i=X(),o=pe(()=>{var y;const I=(y=i.value)==null?void 0:y.el;return I&&typeof I=="object"&&"value"in I?I.value:I}),s=pe(()=>({items:r.items,keyField:r.keyField,direction:r.direction,minItemSize:r.minItemSize,shift:r.shift,cache:r.cache,el:o.value,onResize:()=>a("resize"),onVisible:()=>a("visible")})),c=nh(s),{itemsWithSize:l,forceUpdate:_,scrollToItem:d,scrollToPosition:u,findItemIndex:m,getItemOffset:p,getItemSize:E,cacheSnapshot:S,restoreCache:b,scrollToBottom:h,onScrollerResize:A,onScrollerVisible:D}=c;function L(y,I,v){return{item:y.item,index:I,active:v,itemWithSize:y}}return t({scrollToItem:d,scrollToPosition:u,findItemIndex:m,getItemOffset:p,scrollToBottom:h,getItemSize:E,cacheSnapshot:S,restoreCache:b,forceUpdate:_}),(y,I)=>(M(),ut(ch,Ua({ref_key:"scroller",ref:i,items:K(l),"min-item-size":r.minItemSize,direction:r.direction,cache:r.cache,"key-field":"id","list-tag":r.listTag,"item-tag":r.itemTag},y.$attrs,{onResize:K(A),onVisible:K(D)}),Vf({default:Rt(({item:v,index:C,active:P})=>[Rn(y.$slots,"default",zS(FE(L(v,C,P))))]),empty:Rt(()=>[Rn(y.$slots,"empty")]),_:2},[y.$slots.before?{name:"before",fn:Rt(()=>[Rn(y.$slots,"before")]),key:"0"}:void 0,y.$slots.after?{name:"after",fn:Rt(()=>[Rn(y.$slots,"after")]),key:"1"}:void 0]),1040,["items","min-item-size","direction","cache","list-tag","item-tag","onResize","onVisible"]))}});function dh(e,t,n){const r=cr("vscrollMeasurementContext"),a=cr("vscrollAnchorRegistry",null),i=rS(e,t,r,n);return un(()=>{i.mount()}),a&&$e([i.id,i.finalActive,()=>ge(t)],([o,s,c],[l,_,d])=>{d&&d!==c&&a.delete(d),c&&a.set(c,{active:s,id:o})},{immediate:!0}),Kt(()=>{const o=ge(t);a&&o&&a.delete(o),i.unmount()}),{id:i.id,size:i.size,finalActive:i.finalActive,updateSize:i.updateSize}}const uh=Me({__name:"DynamicScrollerItem",props:{item:{},watchData:{type:Boolean,default:!1},active:{type:Boolean},index:{default:void 0},sizeDependencies:{default:null},emitResize:{type:Boolean,default:!1},tag:{default:"div"}},emits:["resize"],setup(e,{emit:t}){const n=e,r=t,a=X();return dh(n,a,{onResize:i=>r("resize",i)}),(i,o)=>(M(),ut(oi(n.tag),{ref_key:"el",ref:a},{default:Rt(()=>[Rn(i.$slots,"default")]),_:3},512))}});function Md(e){if(!e)return"";const t=new Date(e);if(isNaN(t))return"";const n=Date.now()-t;return n<6e4?"just now":n<36e5?`${Math.floor(n/6e4)}m ago`:n<864e5?t.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}):t.toLocaleDateString()}function c_(e){const t=X(Md(e.value));let n=null;function r(){t.value=Md(e.value)}return un(()=>{r(),n=setInterval(r,3e4)}),gr(()=>{n&&clearInterval(n)}),t}const Ya=X(!1),_S=Rr(""),kc=[];function ph(){return{visible:Ya,message:_S}}function mh(){return function(t){return _S.value=t,Ya.value=!0,new Promise(n=>{kc.push(n)})}}function Ld(e){Ya.value=!1;const t=kc.shift();t==null||t(e),kc.length===0&&(Ya.value=!1)}const Yt=(e,t)=>{const n=e.__vccOpts||e;for(const[r,a]of t)n[r]=a;return n},gh={class:"session-icons"},Eh={key:0,class:"ph ph-push-pin session-pin-icon",title:"Pinned"},Sh={key:1,class:"ph ph-clock session-recall-icon",title:"Scheduled recall pending"},fh={class:"session-info"},bh={class:"session-name-row"},Th=["innerHTML"],hh=["innerHTML"],vh={key:1,class:"session-time"},Rh=["title"],Ch={__name:"SessionItem",props:{session:{type:Object,required:!0},active:{type:Boolean,default:!1},searchQuery:{type:String,default:""}},emits:["select","delete","pin","cancel-recall","skip-recall"],setup(e,{emit:t}){const n=e,r=t,a=mh(),i=pe(()=>{const p=n.session.session_id??"";return n.session.name||p.slice(0,8)}),o=pe(()=>n.searchQuery&&n.session.match_preview?n.session.match_preview:n.session.preview),s=pe(()=>n.session.last_active),c=c_(s);function l(p){return typeof p!="string"?String(p??""):p.replace(/&/g,"&").replace(/
/g,">")}function _(p,E){if(!E||!p)return l(p);const S=l(E.toLowerCase()),b=l(p),h=[];let A=0;const D=b.toLowerCase();for(;;){const L=D.indexOf(S,A);if(L===-1)break;L>A&&h.push(b.slice(A,L)),h.push(`${b.slice(L,L+E.length)}`),A=L+E.length}return A_(i.value,n.searchQuery)),u=pe(()=>_(o.value,n.searchQuery));async function m(){await a("Delete this conversation?")&&r("delete")}return(p,E)=>(M(),Y("div",{class:Ye(["session-item",{"is-active":e.active,"is-pinned":e.session.pinned,"has-recall":e.session.has_pending_recall}]),onClick:E[4]||(E[4]=S=>r("select"))},[R("div",gh,[e.session.pinned?(M(),Y("i",Eh)):Re("",!0),e.session.has_pending_recall?(M(),Y("i",Sh)):Re("",!0)]),R("div",fh,[R("div",bh,[R("span",{class:"session-name",innerHTML:d.value},null,8,Th)]),o.value?(M(),Y("div",{key:0,class:"session-preview",innerHTML:u.value},null,8,hh)):Re("",!0),K(c)?(M(),Y("div",vh,xe(K(c)),1)):Re("",!0)]),R("div",{class:"session-actions",onClick:E[3]||(E[3]=sa(()=>{},["stop"]))},[e.session.has_pending_recall?(M(),Y("button",{key:0,class:"btn-icon",title:"Cancel recall",onClick:E[0]||(E[0]=S=>r("cancel-recall"))},[...E[5]||(E[5]=[R("i",{class:"ph ph-clock-slash"},null,-1)])])):Re("",!0),e.session.has_pending_recall?(M(),Y("button",{key:1,class:"btn-icon",title:"Skip next",onClick:E[1]||(E[1]=S=>r("skip-recall"))},[...E[6]||(E[6]=[R("i",{class:"ph ph-skip-forward"},null,-1)])])):Re("",!0),R("button",{class:"btn-icon",title:e.session.pinned?"Unpin":"Pin",onClick:E[2]||(E[2]=S=>r("pin"))},[R("i",{class:Ye(e.session.pinned?"ph ph-push-pin-slash":"ph ph-push-pin")},null,2)],8,Rh),R("button",{class:"btn-icon",title:"Delete",onClick:m},[...E[7]||(E[7]=[R("i",{class:"ph ph-trash"},null,-1)])])])],2))}},Nh=Yt(Ch,[["__scopeId","data-v-73f7dfc6"]]),Oh={class:"ptr-label"},yh={key:0,class:"sessions-loading"},Ih={key:1,class:"empty-sessions"},Ah={key:2,class:"empty-sessions"},Dh={key:4,class:"sessions-loading sessions-loading-more"},wd=80,xh=120,Mh={__name:"SessionList",emits:["select"],setup(e,{emit:t}){const n=t,r=Cn(),a=Qt(),i=ua();$e(()=>i.selectedProfileId,I=>{I&&I!==r.currentProfileId&&r.fetchSessions(I)});async function o(I){await a.loadSession(I.session_id),n("select",I)}async function s(I){const v=I.session_id===a.currentId;await r.deleteSession(I.session_id),v&&a.clearSession()}async function c(I){await r.pinSession(I.session_id,!I.pinned)}async function l(I){try{await eS(I.session_id),r.updateRecallStatus(I.session_id,!1)}catch(v){console.error("cancel recall failed",v)}}async function _(I){try{await tS(I.session_id)}catch(v){console.error("skip recall failed",v)}}function d(I){const v=I.target;v.scrollHeight-v.scrollTop-v.clientHeight<160&&r.fetchMoreSessions()}const u=X(!1),m=X(0),p=X(!1),E=X(null),S=pe(()=>({transform:`translateY(${Math.min(m.value,xh)}px)`,opacity:u.value?Math.min(m.value/wd,1):0})),b=pe(()=>r.loading?"Refreshing...":p.value?"Release to refresh":"Pull to refresh");let h=0,A=0;function D(I){var C,P;const v=(C=E.value)==null?void 0:C.$el;v&&(A=v.scrollTop||0,!(A>2)&&(h=((P=I.touches[0])==null?void 0:P.clientY)??0,u.value=!1,m.value=0,p.value=!1))}function L(I){var P;if(A>2||!h)return;const C=(((P=I.touches[0])==null?void 0:P.clientY)??0)-h;if(C<=0){u.value=!1;return}C>4&&I.preventDefault(),u.value=!0,m.value=C,p.value=C>=wd}function y(){p.value&&!r.loading&&r.fetchSessions(i.selectedProfileId),u.value=!1,m.value=0,p.value=!1,h=0,A=0}return(I,v)=>(M(),Y("div",{class:"session-list-wrap",onTouchstart:D,onTouchmove:L,onTouchend:y},[R("div",{class:Ye(["ptr-indicator",{"ptr-active":u.value&&!K(r).loading}]),style:On(S.value)},[R("span",{class:Ye(["ptr-spinner",{"ptr-spinning":p.value}])},null,2),R("span",Oh,xe(b.value),1)],6),K(r).loading&&!K(r).sessions.length?(M(),Y("div",yh,[...v[0]||(v[0]=[R("span",{class:"sessions-spinner"},null,-1),R("p",null,"Loading conversations...",-1)])])):K(r).sessions.length?K(r).filteredSessions.length?Re("",!0):(M(),Y("div",Ah,[...v[2]||(v[2]=[R("i",{class:"ph ph-faders"},null,-1),R("p",null,"No conversations match the current filter",-1)])])):(M(),Y("div",Ih,[...v[1]||(v[1]=[R("i",{class:"ph ph-chat-dots"},null,-1),R("p",null,"No conversations yet",-1)])])),K(r).filteredSessions.length?(M(),ut(K(_h),{key:K(r).searchActive?"search":"all",ref_key:"scrollerRef",ref:E,class:Ye(["session-scroller",{"ptr-pulled":u.value}]),items:K(r).filteredSessions,"min-item-size":64,"key-field":"session_id",onScrollPassive:d},{default:Rt(({item:C,index:P,active:U})=>[ke(K(uh),{item:C,active:U,"data-index":P},{default:Rt(()=>[ke(Nh,{session:C,active:C.session_id===K(a).currentId,"search-query":K(r).searchActive?K(r).searchQuery:"",onSelect:x=>o(C),onDelete:x=>s(C),onPin:x=>c(C),onCancelRecall:x=>l(C),onSkipRecall:x=>_(C)},null,8,["session","active","search-query","onSelect","onDelete","onPin","onCancelRecall","onSkipRecall"])]),_:2},1032,["item","active","data-index"])]),_:1},8,["class","items"])):Re("",!0),K(r).loadingMore?(M(),Y("div",Dh,[...v[3]||(v[3]=[R("span",{class:"sessions-spinner"},null,-1)])])):Re("",!0)],32))}},Lh=Yt(Mh,[["__scopeId","data-v-5a757df4"]]),wh={class:"sidebar-header"},Ph={class:"sidebar-logo"},kh={class:"sidebar-controls-row"},Uh={class:"sidebar-profile-select"},Fh=["value"],Bh=["value"],Gh={class:"sidebar-sessions"},Yh={class:"sessions-header"},qh={class:"sessions-label"},$h={class:"sessions-header-actions"},Hh={class:"sidebar-footer"},Vh=["href"],zh={class:"user-name"},Wh={class:"sidebar-footer-actions"},Kh={key:0,href:"/admin",target:"_blank",rel:"noopener noreferrer",class:"btn-icon without-hover admin-link",title:"Admin"},Qh={__name:"AppSidebar",props:{mobileOpen:Boolean},emits:["close"],setup(e,{emit:t}){const n=e,r=t,a=ua(),i=Cn(),o=Qt(),s=i_(),c=X(!1),l=X(""),_=X(null);let d=null;function u(){var L;const A=((L=_.value)==null?void 0:L.$el)??_.value;if(!A)return;const D=A.querySelector("input");D==null||D.focus()}$e(()=>o.currentProfileId,A=>{A&&(a.selectedProfileId=A)});function m(){c.value=!c.value,c.value&&(setTimeout(u,50),i.searchQuery&&(l.value=i.searchQuery,i.restoreSearch()))}function p(){c.value&&(c.value=!1,i.exitSearch(),i.fetchSessions(a.selectedProfileId))}function E(){l.value="",i.clearSearch(),i.fetchSessions(a.selectedProfileId)}$e(l,A=>{if(d&&clearTimeout(d),!A){i.clearSearch(),i.fetchSessions(a.selectedProfileId);return}d=setTimeout(()=>{i.setSearch(A),i.fetchSessions()},300)}),$e(()=>a.selectedProfileId,()=>{c.value&&(c.value=!1,i.exitSearch(),i.fetchSessions(a.selectedProfileId))});async function S(){const A=await i.createSession(a.selectedProfileId);await o.loadSession(A.session_id),r("close")}async function b(A){var D;i.searchActive&&A.profile_id&&(a.selectedProfileId=A.profile_id),await o.loadSession(A.session_id,(D=A.match_indices)==null?void 0:D[0]),c.value=!1,i.exitSearch(),i.fetchSessions(a.selectedProfileId),r("close")}function h(A){(A.ctrlKey||A.metaKey)&&A.key==="k"&&(A.preventDefault(),m())}return un(()=>window.addEventListener("keydown",h)),Kt(()=>window.removeEventListener("keydown",h)),(A,D)=>{var C,P,U,x,j,ie,he;const L=Pt("GnIconButton"),y=Pt("GnButton"),I=Pt("GnSearchField"),v=Pt("GnAvatar");return M(),Y("aside",{class:Ye(["app-sidebar",{"is-mobile-open":n.mobileOpen}])},[R("div",wh,[R("div",Ph,[D[5]||(D[5]=R("img",{src:o_,alt:"Navi"},null,-1)),D[6]||(D[6]=R("span",null,"Navi",-1)),ke(L,{icon:"ph ph-x",label:"Close",class:"sidebar-close-btn",onClick:D[0]||(D[0]=ae=>r("close"))})]),R("div",kh,[R("div",Uh,[R("select",{value:K(a).selectedProfileId,onChange:D[1]||(D[1]=ae=>K(a).selectedProfileId=ae.target.value)},[(M(!0),Y(et,null,Jt(K(a).profiles,ae=>(M(),Y("option",{key:ae.id,value:ae.id},xe(ae.name),9,Bh))),128))],40,Fh)]),ke(y,{variant:"primary",icon:"ph ph-plus",onClick:S},{default:Rt(()=>[...D[7]||(D[7]=[At(" New Chat ",-1)])]),_:1})])]),R("div",{class:Ye(["sidebar-search",{"is-open":c.value}])},[R("div",{class:Ye(["sidebar-search-inner",{"is-loading":K(i).loading&&K(i).searchActive}])},[ke(I,{ref_key:"searchFieldEl",ref:_,modelValue:l.value,"onUpdate:modelValue":D[2]||(D[2]=ae=>l.value=ae),placeholder:"Search conversations...",compact:"",clearable:"",onClear:E,onKeydown:Dc(p,["esc"])},null,8,["modelValue"])],2)],2),R("div",Gh,[R("div",Yh,[R("div",qh,[K(i).searchActive?(M(),Y(et,{key:0},[At(xe(K(i).sessions.length)+" result"+xe(K(i).sessions.length===1?"":"s"),1)],64)):(M(),Y(et,{key:1},[At("Conversations")],64))]),R("div",$h,[ke(L,{icon:"ph ph-clock",label:"Pending recalls only",class:Ye(["recall-filter-btn",{active:K(i).hasPendingRecallFilter}]),onClick:D[3]||(D[3]=ae=>K(i).hasPendingRecallFilter=!K(i).hasPendingRecallFilter)},null,8,["class"]),ke(L,{icon:"ph ph-magnifying-glass",label:"Search",class:Ye(["search-toggle-btn",{active:c.value||K(i).searchActive}]),onClick:m},null,8,["class"]),ke(L,{icon:"ph ph-arrow-clockwise",label:"Refresh",class:Ye(["sessions-refresh-btn",{"is-spinning":K(i).loading}]),onClick:D[4]||(D[4]=ae=>K(i).fetchSessions(K(a).selectedProfileId))},null,8,["class"])])]),ke(Lh,{onSelect:b})]),R("div",Hh,[K(s).isAuthenticated?(M(),Y(et,{key:0},[R("a",{class:"user-info",href:(C=K(s).user)==null?void 0:C.profile_url,target:"_blank",rel:"noopener noreferrer",title:"Open profile in gnexus-auth"},[ke(v,{size:"sm",src:((P=K(s).user)==null?void 0:P.avatar_url)||"",alt:((U=K(s).user)==null?void 0:U.display_name)||"avatar",initials:(((x=K(s).user)==null?void 0:x.display_name)||((j=K(s).user)==null?void 0:j.email)||"?").charAt(0).toUpperCase()},null,8,["src","alt","initials"]),R("span",zh,xe(((ie=K(s).user)==null?void 0:ie.display_name)||((he=K(s).user)==null?void 0:he.email)),1)],8,Vh),R("div",Wh,[K(s).isAdmin?(M(),Y("a",Kh,[...D[8]||(D[8]=[R("i",{class:"ph ph-shield-check"},null,-1)])])):Re("",!0),ke(L,{icon:"ph ph-sign-out",label:"Logout","without-hover":"",onClick:K(s).logout},null,8,["onClick"])])],64)):(M(),ut(y,{key:1,variant:"primary",icon:"ph ph-sign-in",onClick:K(s).login},{default:Rt(()=>[...D[9]||(D[9]=[At(" Login ",-1)])]),_:1},8,["onClick"]))])],2)}}},Xh=Yt(Qh,[["__scopeId","data-v-780609b7"]]),Zh={__name:"ConfirmDialog",setup(e){const{visible:t,message:n}=ph();function r(){Ld(!0)}function a(){Ld(!1)}return(i,o)=>{const s=Pt("GnConfirmDialog");return M(),ut(s,{open:K(t),"onUpdate:open":o[0]||(o[0]=c=>Nt(t)?t.value=c:null),message:K(n),title:"Requires confirmation","cancel-text":"No","confirm-text":"Yes","confirm-variant":"warning",onConfirm:r,onCancel:a},null,8,["open","message"])}}},ki=X(null);function pi(){function e(n){ki.value=n}function t(){ki.value=null}return{src:ki,open:e,close:t}}const Jh={key:0,class:"modal a-show","aria-hidden":"false"},jh={class:"modal-dialog",role:"dialog","aria-modal":"true",tabindex:"-1"},ev={class:"modal-header"},tv={class:"modal-panel lightbox-panel"},nv={class:"modal-body"},rv=["src"],av={key:1,class:"lightbox-error"},iv={__name:"ImageLightbox",setup(e){const{src:t,close:n}=pi(),r=X(!1);return $e(t,a=>{document.body.style.overflow=a?"hidden":"",r.value=!1}),(a,i)=>(M(),ut(ri,{to:"body"},[K(t)?(M(),Y("div",Jh,[R("div",{class:"modal-backdrop",onClick:i[0]||(i[0]=(...o)=>K(n)&&K(n)(...o))}),R("div",jh,[R("header",ev,[i[3]||(i[3]=R("h4",{class:"modal-title"},"Photo",-1)),R("button",{class:"btn-icon modal-close",type:"button","aria-label":"Close",onClick:i[1]||(i[1]=(...o)=>K(n)&&K(n)(...o))},"✕")]),R("div",tv,[R("div",nv,[r.value?(M(),Y("div",av,[...i[4]||(i[4]=[R("i",{class:"ph ph-image-broken"},null,-1),R("span",null,"Failed to load image",-1)])])):(M(),Y("img",{key:0,src:K(t),class:"lightbox-img",onError:i[2]||(i[2]=o=>r.value=!0)},null,40,rv))])])])])):Re("",!0)]))}},va=X("");function dS(){function e(n){va.value=n}function t(){const n=va.value;return va.value="",n}return{pendingQuote:va,requestQuote:e,consumeQuote:t}}const ov={__name:"SelectionToolbar",setup(e){const{requestQuote:t}=dS(),n=X(!1),r=X({x:0,y:0});let a="";function i(){const _=window.getSelection();if(!_||_.isCollapsed||!_.toString().trim())return null;const d=_.getRangeAt(0),u=d.commonAncestorContainer;return(u.nodeType===Node.TEXT_NODE?u.parentElement:u).closest(".msg-assistant-content")?{text:_.toString().trim(),range:d}:null}function o(){const _=window.getSelection();if(!_||_.isCollapsed||!_.rangeCount){n.value=!1;return}const u=_.getRangeAt(0).getBoundingClientRect();if(!u.width&&!u.height){n.value=!1;return}r.value={x:Math.round(u.left+u.width/2),y:Math.round(u.top-44)}}function s(){setTimeout(()=>{const _=i();if(!_){n.value=!1;return}a=_.text,o(),n.value=!0},10)}function c(){const _=window.getSelection();(!_||_.isCollapsed)&&(n.value=!1)}function l(){var _;a&&(t(a),(_=window.getSelection())==null||_.removeAllRanges(),n.value=!1)}return un(()=>{document.addEventListener("mouseup",s),document.addEventListener("selectionchange",c),document.addEventListener("scroll",o,!0)}),gr(()=>{document.removeEventListener("mouseup",s),document.removeEventListener("selectionchange",c),document.removeEventListener("scroll",o,!0)}),(_,d)=>{const u=Pt("GnButton");return M(),ut(ri,{to:"body"},[n.value?(M(),Y("div",{key:0,class:"selection-toolbar",style:On({top:r.value.y+"px",left:r.value.x+"px"}),onMousedown:d[0]||(d[0]=sa(()=>{},["prevent"]))},[ke(u,{variant:"warning",size:"sm",icon:"ph ph-quotes",style:{color:"#000"},title:"Reply to selection",onClick:l},{default:Rt(()=>[...d[1]||(d[1]=[At(" Reply ",-1)])]),_:1})],36)):Re("",!0)])}}},sv=Yt(ov,[["__scopeId","data-v-81606e7c"]]);function dr(e){if(!e)return"";let t;try{t=new URL(e,window.location.origin)}catch{return e}return t.origin===window.location.origin?`${t.pathname}${t.search}${t.hash}`:t.href}function qa(e){return e?new URL(e,window.location.origin).href:""}function lv(e,t){const n=dr(e);return!n||!t?n:`${n}${n.includes("?")?"&":"?"}v=${encodeURIComponent(t)}`}function uS(e,t){const n=new URL(`/content-viewers/${e}.html`,window.location.origin);return n.searchParams.set("url",t),n.href}function cv(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Ui,Pd;function _v(){if(Pd)return Ui;Pd=1;function e(N){return N instanceof Map?N.clear=N.delete=N.set=function(){throw new Error("map is read-only")}:N instanceof Set&&(N.add=N.clear=N.delete=function(){throw new Error("set is read-only")}),Object.freeze(N),Object.getOwnPropertyNames(N).forEach(V=>{const re=N[V],Ie=typeof re;(Ie==="object"||Ie==="function")&&!Object.isFrozen(re)&&e(re)}),N}class t{constructor(V){V.data===void 0&&(V.data={}),this.data=V.data,this.isMatchIgnored=!1}ignoreMatch(){this.isMatchIgnored=!0}}function n(N){return N.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function r(N,...V){const re=Object.create(null);for(const Ie in N)re[Ie]=N[Ie];return V.forEach(function(Ie){for(const it in Ie)re[it]=Ie[it]}),re}const a="",i=N=>!!N.scope,o=(N,{prefix:V})=>{if(N.startsWith("language:"))return N.replace("language:","language-");if(N.includes(".")){const re=N.split(".");return[`${V}${re.shift()}`,...re.map((Ie,it)=>`${Ie}${"_".repeat(it+1)}`)].join(" ")}return`${V}${N}`};class s{constructor(V,re){this.buffer="",this.classPrefix=re.classPrefix,V.walk(this)}addText(V){this.buffer+=n(V)}openNode(V){if(!i(V))return;const re=o(V.scope,{prefix:this.classPrefix});this.span(re)}closeNode(V){i(V)&&(this.buffer+=a)}value(){return this.buffer}span(V){this.buffer+=``}}const c=(N={})=>{const V={children:[]};return Object.assign(V,N),V};class l{constructor(){this.rootNode=c(),this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(V){this.top.children.push(V)}openNode(V){const re=c({scope:V});this.add(re),this.stack.push(re)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(V){return this.constructor._walk(V,this.rootNode)}static _walk(V,re){return typeof re=="string"?V.addText(re):re.children&&(V.openNode(re),re.children.forEach(Ie=>this._walk(V,Ie)),V.closeNode(re)),V}static _collapse(V){typeof V!="string"&&V.children&&(V.children.every(re=>typeof re=="string")?V.children=[V.children.join("")]:V.children.forEach(re=>{l._collapse(re)}))}}class _ extends l{constructor(V){super(),this.options=V}addText(V){V!==""&&this.add(V)}startScope(V){this.openNode(V)}endScope(){this.closeNode()}__addSublanguage(V,re){const Ie=V.root;re&&(Ie.scope=`language:${re}`),this.add(Ie)}toHTML(){return new s(this,this.options).value()}finalize(){return this.closeAllNodes(),!0}}function d(N){return N?typeof N=="string"?N:N.source:null}function u(N){return E("(?=",N,")")}function m(N){return E("(?:",N,")*")}function p(N){return E("(?:",N,")?")}function E(...N){return N.map(re=>d(re)).join("")}function S(N){const V=N[N.length-1];return typeof V=="object"&&V.constructor===Object?(N.splice(N.length-1,1),V):{}}function b(...N){return"("+(S(N).capture?"":"?:")+N.map(Ie=>d(Ie)).join("|")+")"}function h(N){return new RegExp(N.toString()+"|").exec("").length-1}function A(N,V){const re=N&&N.exec(V);return re&&re.index===0}const D=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;function L(N,{joinWith:V}){let re=0;return N.map(Ie=>{re+=1;const it=re;let We=d(Ie),ce="";for(;We.length>0;){const Se=D.exec(We);if(!Se){ce+=We;break}ce+=We.substring(0,Se.index),We=We.substring(Se.index+Se[0].length),Se[0][0]==="\\"&&Se[1]?ce+="\\"+String(Number(Se[1])+it):(ce+=Se[0],Se[0]==="("&&re++)}return ce}).map(Ie=>`(${Ie})`).join(V)}const y=/\b\B/,I="[a-zA-Z]\\w*",v="[a-zA-Z_]\\w*",C="\\b\\d+(\\.\\d+)?",P="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",U="\\b(0b[01]+)",x="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",j=(N={})=>{const V=/^#![ ]*\//;return N.binary&&(N.begin=E(V,/.*\b/,N.binary,/\b.*/)),r({scope:"meta",begin:V,end:/$/,relevance:0,"on:begin":(re,Ie)=>{re.index!==0&&Ie.ignoreMatch()}},N)},ie={begin:"\\\\[\\s\\S]",relevance:0},he={scope:"string",begin:"'",end:"'",illegal:"\\n",contains:[ie]},ae={scope:"string",begin:'"',end:'"',illegal:"\\n",contains:[ie]},ue={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},Ne=function(N,V,re={}){const Ie=r({scope:"comment",begin:N,end:V,contains:[]},re);Ie.contains.push({scope:"doctag",begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)",end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0});const it=b("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/);return Ie.contains.push({begin:E(/[ ]+/,"(",it,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),Ie},ve=Ne("//","$"),Le=Ne("/\\*","\\*/"),Xe=Ne("#","$"),ze={scope:"number",begin:C,relevance:0},Tt={scope:"number",begin:P,relevance:0},Et={scope:"number",begin:U,relevance:0},st={scope:"regexp",begin:/\/(?=[^/\n]*\/)/,end:/\/[gimuy]*/,contains:[ie,{begin:/\[/,end:/\]/,relevance:0,contains:[ie]}]},Qe={scope:"title",begin:I,relevance:0},F={scope:"title",begin:v,relevance:0},z={begin:"\\.\\s*"+v,relevance:0};var O=Object.freeze({__proto__:null,APOS_STRING_MODE:he,BACKSLASH_ESCAPE:ie,BINARY_NUMBER_MODE:Et,BINARY_NUMBER_RE:U,COMMENT:Ne,C_BLOCK_COMMENT_MODE:Le,C_LINE_COMMENT_MODE:ve,C_NUMBER_MODE:Tt,C_NUMBER_RE:P,END_SAME_AS_BEGIN:function(N){return Object.assign(N,{"on:begin":(V,re)=>{re.data._beginMatch=V[1]},"on:end":(V,re)=>{re.data._beginMatch!==V[1]&&re.ignoreMatch()}})},HASH_COMMENT_MODE:Xe,IDENT_RE:I,MATCH_NOTHING_RE:y,METHOD_GUARD:z,NUMBER_MODE:ze,NUMBER_RE:C,PHRASAL_WORDS_MODE:ue,QUOTE_STRING_MODE:ae,REGEXP_MODE:st,RE_STARTERS_RE:x,SHEBANG:j,TITLE_MODE:Qe,UNDERSCORE_IDENT_RE:v,UNDERSCORE_TITLE_MODE:F});function G(N,V){N.input[N.index-1]==="."&&V.ignoreMatch()}function g(N,V){N.className!==void 0&&(N.scope=N.className,delete N.className)}function T(N,V){V&&N.beginKeywords&&(N.begin="\\b("+N.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",N.__beforeBegin=G,N.keywords=N.keywords||N.beginKeywords,delete N.beginKeywords,N.relevance===void 0&&(N.relevance=0))}function w(N,V){Array.isArray(N.illegal)&&(N.illegal=b(...N.illegal))}function B(N,V){if(N.match){if(N.begin||N.end)throw new Error("begin & end are not supported with match");N.begin=N.match,delete N.match}}function k(N,V){N.relevance===void 0&&(N.relevance=1)}const H=(N,V)=>{if(!N.beforeMatch)return;if(N.starts)throw new Error("beforeMatch cannot be used with starts");const re=Object.assign({},N);Object.keys(N).forEach(Ie=>{delete N[Ie]}),N.keywords=re.keywords,N.begin=E(re.beforeMatch,u(re.begin)),N.starts={relevance:0,contains:[Object.assign(re,{endsParent:!0})]},N.relevance=0,delete re.beforeMatch},J=["of","and","for","in","not","or","if","then","parent","list","value"],ee="keyword";function te(N,V,re=ee){const Ie=Object.create(null);return typeof N=="string"?it(re,N.split(" ")):Array.isArray(N)?it(re,N):Object.keys(N).forEach(function(We){Object.assign(Ie,te(N[We],V,We))}),Ie;function it(We,ce){V&&(ce=ce.map(Se=>Se.toLowerCase())),ce.forEach(function(Se){const Ae=Se.split("|");Ie[Ae[0]]=[We,Z(Ae[0],Ae[1])]})}}function Z(N,V){return V?Number(V):fe(N)?0:1}function fe(N){return J.includes(N.toLowerCase())}const oe={},ne=N=>{console.error(N)},be=(N,...V)=>{console.log(`WARN: ${N}`,...V)},De=(N,V)=>{oe[`${N}/${V}`]||(console.log(`Deprecated as of ${N}. ${V}`),oe[`${N}/${V}`]=!0)},Be=new Error;function tt(N,V,{key:re}){let Ie=0;const it=N[re],We={},ce={};for(let Se=1;Se<=V.length;Se++)ce[Se+Ie]=it[Se],We[Se+Ie]=!0,Ie+=h(V[Se-1]);N[re]=ce,N[re]._emit=We,N[re]._multi=!0}function rt(N){if(Array.isArray(N.begin)){if(N.skip||N.excludeBegin||N.returnBegin)throw ne("skip, excludeBegin, returnBegin not compatible with beginScope: {}"),Be;if(typeof N.beginScope!="object"||N.beginScope===null)throw ne("beginScope must be object"),Be;tt(N,N.begin,{key:"beginScope"}),N.begin=L(N.begin,{joinWith:""})}}function Je(N){if(Array.isArray(N.end)){if(N.skip||N.excludeEnd||N.returnEnd)throw ne("skip, excludeEnd, returnEnd not compatible with endScope: {}"),Be;if(typeof N.endScope!="object"||N.endScope===null)throw ne("endScope must be object"),Be;tt(N,N.end,{key:"endScope"}),N.end=L(N.end,{joinWith:""})}}function $(N){N.scope&&typeof N.scope=="object"&&N.scope!==null&&(N.beginScope=N.scope,delete N.scope)}function Q(N){$(N),typeof N.beginScope=="string"&&(N.beginScope={_wrap:N.beginScope}),typeof N.endScope=="string"&&(N.endScope={_wrap:N.endScope}),rt(N),Je(N)}function le(N){function V(ce,Se){return new RegExp(d(ce),"m"+(N.case_insensitive?"i":"")+(N.unicodeRegex?"u":"")+(Se?"g":""))}class re{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(Se,Ae){Ae.position=this.position++,this.matchIndexes[this.matchAt]=Ae,this.regexes.push([Ae,Se]),this.matchAt+=h(Se)+1}compile(){this.regexes.length===0&&(this.exec=()=>null);const Se=this.regexes.map(Ae=>Ae[1]);this.matcherRe=V(L(Se,{joinWith:"|"}),!0),this.lastIndex=0}exec(Se){this.matcherRe.lastIndex=this.lastIndex;const Ae=this.matcherRe.exec(Se);if(!Ae)return null;const _t=Ae.findIndex((yn,en)=>en>0&&yn!==void 0),Ge=this.matchIndexes[_t];return Ae.splice(0,_t),Object.assign(Ae,Ge)}}class Ie{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(Se){if(this.multiRegexes[Se])return this.multiRegexes[Se];const Ae=new re;return this.rules.slice(Se).forEach(([_t,Ge])=>Ae.addRule(_t,Ge)),Ae.compile(),this.multiRegexes[Se]=Ae,Ae}resumingScanAtSamePosition(){return this.regexIndex!==0}considerAll(){this.regexIndex=0}addRule(Se,Ae){this.rules.push([Se,Ae]),Ae.type==="begin"&&this.count++}exec(Se){const Ae=this.getMatcher(this.regexIndex);Ae.lastIndex=this.lastIndex;let _t=Ae.exec(Se);if(this.resumingScanAtSamePosition()&&!(_t&&_t.index===this.lastIndex)){const Ge=this.getMatcher(0);Ge.lastIndex=this.lastIndex+1,_t=Ge.exec(Se)}return _t&&(this.regexIndex+=_t.position+1,this.regexIndex===this.count&&this.considerAll()),_t}}function it(ce){const Se=new Ie;return ce.contains.forEach(Ae=>Se.addRule(Ae.begin,{rule:Ae,type:"begin"})),ce.terminatorEnd&&Se.addRule(ce.terminatorEnd,{type:"end"}),ce.illegal&&Se.addRule(ce.illegal,{type:"illegal"}),Se}function We(ce,Se){const Ae=ce;if(ce.isCompiled)return Ae;[g,B,Q,H].forEach(Ge=>Ge(ce,Se)),N.compilerExtensions.forEach(Ge=>Ge(ce,Se)),ce.__beforeBegin=null,[T,w,k].forEach(Ge=>Ge(ce,Se)),ce.isCompiled=!0;let _t=null;return typeof ce.keywords=="object"&&ce.keywords.$pattern&&(ce.keywords=Object.assign({},ce.keywords),_t=ce.keywords.$pattern,delete ce.keywords.$pattern),_t=_t||/\w+/,ce.keywords&&(ce.keywords=te(ce.keywords,N.case_insensitive)),Ae.keywordPatternRe=V(_t,!0),Se&&(ce.begin||(ce.begin=/\B|\b/),Ae.beginRe=V(Ae.begin),!ce.end&&!ce.endsWithParent&&(ce.end=/\B|\b/),ce.end&&(Ae.endRe=V(Ae.end)),Ae.terminatorEnd=d(Ae.end)||"",ce.endsWithParent&&Se.terminatorEnd&&(Ae.terminatorEnd+=(ce.end?"|":"")+Se.terminatorEnd)),ce.illegal&&(Ae.illegalRe=V(ce.illegal)),ce.contains||(ce.contains=[]),ce.contains=[].concat(...ce.contains.map(function(Ge){return Te(Ge==="self"?ce:Ge)})),ce.contains.forEach(function(Ge){We(Ge,Ae)}),ce.starts&&We(ce.starts,Se),Ae.matcher=it(Ae),Ae}if(N.compilerExtensions||(N.compilerExtensions=[]),N.contains&&N.contains.includes("self"))throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return N.classNameAliases=r(N.classNameAliases||{}),We(N)}function we(N){return N?N.endsWithParent||we(N.starts):!1}function Te(N){return N.variants&&!N.cachedVariants&&(N.cachedVariants=N.variants.map(function(V){return r(N,{variants:null},V)})),N.cachedVariants?N.cachedVariants:we(N)?r(N,{starts:N.starts?r(N.starts):null}):Object.isFrozen(N)?r(N):N}var ye="11.11.1";class qe extends Error{constructor(V,re){super(V),this.name="HTMLInjectionError",this.html=re}}const q=n,W=r,_e=Symbol("nomatch"),Ee=7,Ze=function(N){const V=Object.create(null),re=Object.create(null),Ie=[];let it=!0;const We="Could not find the language '{}', did you forget to load/include a language module?",ce={disableAutodetect:!0,name:"Plain text",contains:[]};let Se={ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",cssSelector:"pre code",languages:null,__emitter:_};function Ae(se){return Se.noHighlightRe.test(se)}function _t(se){let Pe=se.className+" ";Pe+=se.parentNode?se.parentNode.className:"";const nt=Se.languageDetectRe.exec(Pe);if(nt){const St=vt(nt[1]);return St||(be(We.replace("{}",nt[1])),be("Falling back to no-highlight mode for this block.",se)),St?nt[1]:"no-highlight"}return Pe.split(/\s+/).find(St=>Ae(St)||vt(St))}function Ge(se,Pe,nt){let St="",It="";typeof Pe=="object"?(St=se,nt=Pe.ignoreIllegals,It=Pe.language):(De("10.7.0","highlight(lang, code, ...args) has been deprecated."),De("10.7.0",`Please use highlight(code, options) instead.
-https://github.com/highlightjs/highlight.js/issues/2277`),It=se,St=Pe),nt===void 0&&(nt=!0);const nn={code:St,language:It};Mr("before:highlight",nn);const An=nn.result?nn.result:yn(nn.language,nn.code,nt);return An.code=nn.code,Mr("after:highlight",An),An}function yn(se,Pe,nt,St){const It=Object.create(null);function nn(me,Oe){return me.keywords[Oe]}function An(){if(!He.keywords){xt.addText(gt);return}let me=0;He.keywordPatternRe.lastIndex=0;let Oe=He.keywordPatternRe.exec(gt),Ke="";for(;Oe;){Ke+=gt.substring(me,Oe.index);const lt=rn.case_insensitive?Oe[0].toLowerCase():Oe[0],Mt=nn(He,lt);if(Mt){const[an,D_]=Mt;if(xt.addText(Ke),Ke="",It[lt]=(It[lt]||0)+1,It[lt]<=Ee&&(Jn+=D_),an.startsWith("_"))Ke+=Oe[0];else{const x_=rn.classNameAliases[an]||an;ln(Oe[0],x_)}}else Ke+=Oe[0];me=He.keywordPatternRe.lastIndex,Oe=He.keywordPatternRe.exec(gt)}Ke+=gt.substring(me),xt.addText(Ke)}function Lr(){if(gt==="")return;let me=null;if(typeof He.subLanguage=="string"){if(!V[He.subLanguage]){xt.addText(gt);return}me=yn(He.subLanguage,gt,!0,Ea[He.subLanguage]),Ea[He.subLanguage]=me._top}else me=In(gt,He.subLanguage.length?He.subLanguage:null);He.relevance>0&&(Jn+=me.relevance),xt.__addSublanguage(me._emitter,me.language)}function Wt(){He.subLanguage!=null?Lr():An(),gt=""}function ln(me,Oe){me!==""&&(xt.startScope(Oe),xt.addText(me),xt.endScope())}function Si(me,Oe){let Ke=1;const lt=Oe.length-1;for(;Ke<=lt;){if(!me._emit[Ke]){Ke++;continue}const Mt=rn.classNameAliases[me[Ke]]||me[Ke],an=Oe[Ke];Mt?ln(an,Mt):(gt=an,An(),gt=""),Ke++}}function fi(me,Oe){return me.scope&&typeof me.scope=="string"&&xt.openNode(rn.classNameAliases[me.scope]||me.scope),me.beginScope&&(me.beginScope._wrap?(ln(gt,rn.classNameAliases[me.beginScope._wrap]||me.beginScope._wrap),gt=""):me.beginScope._multi&&(Si(me.beginScope,Oe),gt="")),He=Object.create(me,{parent:{value:He}}),He}function bi(me,Oe,Ke){let lt=A(me.endRe,Ke);if(lt){if(me["on:end"]){const Mt=new t(me);me["on:end"](Oe,Mt),Mt.isMatchIgnored&&(lt=!1)}if(lt){for(;me.endsParent&&me.parent;)me=me.parent;return me}}if(me.endsWithParent)return bi(me.parent,Oe,Ke)}function O_(me){return He.matcher.regexIndex===0?(gt+=me[0],1):(Ur=!0,0)}function y_(me){const Oe=me[0],Ke=me.rule,lt=new t(Ke),Mt=[Ke.__beforeBegin,Ke["on:begin"]];for(const an of Mt)if(an&&(an(me,lt),lt.isMatchIgnored))return O_(Oe);return Ke.skip?gt+=Oe:(Ke.excludeBegin&&(gt+=Oe),Wt(),!Ke.returnBegin&&!Ke.excludeBegin&&(gt=Oe)),fi(Ke,me),Ke.returnBegin?0:Oe.length}function I_(me){const Oe=me[0],Ke=Pe.substring(me.index),lt=bi(He,me,Ke);if(!lt)return _e;const Mt=He;He.endScope&&He.endScope._wrap?(Wt(),ln(Oe,He.endScope._wrap)):He.endScope&&He.endScope._multi?(Wt(),Si(He.endScope,me)):Mt.skip?gt+=Oe:(Mt.returnEnd||Mt.excludeEnd||(gt+=Oe),Wt(),Mt.excludeEnd&&(gt=Oe));do He.scope&&xt.closeNode(),!He.skip&&!He.subLanguage&&(Jn+=He.relevance),He=He.parent;while(He!==lt.parent);return lt.starts&&fi(lt.starts,me),Mt.returnEnd?0:Oe.length}function A_(){const me=[];for(let Oe=He;Oe!==rn;Oe=Oe.parent)Oe.scope&&me.unshift(Oe.scope);me.forEach(Oe=>xt.openNode(Oe))}let wr={};function ga(me,Oe){const Ke=Oe&&Oe[0];if(gt+=me,Ke==null)return Wt(),0;if(wr.type==="begin"&&Oe.type==="end"&&wr.index===Oe.index&&Ke===""){if(gt+=Pe.slice(Oe.index,Oe.index+1),!it){const lt=new Error(`0 width match regex (${se})`);throw lt.languageName=se,lt.badRule=wr.rule,lt}return 1}if(wr=Oe,Oe.type==="begin")return y_(Oe);if(Oe.type==="illegal"&&!nt){const lt=new Error('Illegal lexeme "'+Ke+'" for mode "'+(He.scope||"")+'"');throw lt.mode=He,lt}else if(Oe.type==="end"){const lt=I_(Oe);if(lt!==_e)return lt}if(Oe.type==="illegal"&&Ke==="")return gt+=`
-`,1;if(kr>1e5&&kr>Oe.index*3)throw new Error("potential infinite loop, way more iterations than matches");return gt+=Ke,Ke.length}const rn=vt(se);if(!rn)throw ne(We.replace("{}",se)),new Error('Unknown language: "'+se+'"');const Ti=le(rn);let Pr="",He=St||Ti;const Ea={},xt=new Se.__emitter(Se);A_();let gt="",Jn=0,mn=0,kr=0,Ur=!1;try{if(rn.__emitTokens)rn.__emitTokens(Pe,xt);else{for(He.matcher.considerAll();;){kr++,Ur?Ur=!1:He.matcher.considerAll(),He.matcher.lastIndex=mn;const me=He.matcher.exec(Pe);if(!me)break;const Oe=Pe.substring(mn,me.index),Ke=ga(Oe,me);mn=me.index+Ke}ga(Pe.substring(mn))}return xt.finalize(),Pr=xt.toHTML(),{language:se,value:Pr,relevance:Jn,illegal:!1,_emitter:xt,_top:He}}catch(me){if(me.message&&me.message.includes("Illegal"))return{language:se,value:q(Pe),illegal:!0,relevance:0,_illegalBy:{message:me.message,index:mn,context:Pe.slice(mn-100,mn+100),mode:me.mode,resultSoFar:Pr},_emitter:xt};if(it)return{language:se,value:q(Pe),illegal:!1,relevance:0,errorRaised:me,_emitter:xt,_top:He};throw me}}function en(se){const Pe={value:q(se),illegal:!1,relevance:0,_top:ce,_emitter:new Se.__emitter(Se)};return Pe._emitter.addText(se),Pe}function In(se,Pe){Pe=Pe||Se.languages||Object.keys(V);const nt=en(se),St=Pe.filter(vt).filter(Ei).map(Wt=>yn(Wt,se,!1));St.unshift(nt);const It=St.sort((Wt,ln)=>{if(Wt.relevance!==ln.relevance)return ln.relevance-Wt.relevance;if(Wt.language&&ln.language){if(vt(Wt.language).supersetOf===ln.language)return 1;if(vt(ln.language).supersetOf===Wt.language)return-1}return 0}),[nn,An]=It,Lr=nn;return Lr.secondBest=An,Lr}function ma(se,Pe,nt){const St=Pe&&re[Pe]||nt;se.classList.add("hljs"),se.classList.add(`language-${St}`)}function je(se){let Pe=null;const nt=_t(se);if(Ae(nt))return;if(Mr("before:highlightElement",{el:se,language:nt}),se.dataset.highlighted){console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.",se);return}if(se.children.length>0&&(Se.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."),console.warn("https://github.com/highlightjs/highlight.js/wiki/security"),console.warn("The element with unescaped HTML:"),console.warn(se)),Se.throwUnescapedHTML))throw new qe("One of your code blocks includes unescaped HTML.",se.innerHTML);Pe=se;const St=Pe.textContent,It=nt?Ge(St,{language:nt,ignoreIllegals:!0}):In(St);se.innerHTML=It.value,se.dataset.highlighted="yes",ma(se,nt,It.language),se.result={language:It.language,re:It.relevance,relevance:It.relevance},It.secondBest&&(se.secondBest={language:It.secondBest.language,relevance:It.secondBest.relevance}),Mr("after:highlightElement",{el:se,result:It,text:St})}function yt(se){Se=W(Se,se)}const tn=()=>{Hn(),De("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")};function sn(){Hn(),De("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.")}let $n=!1;function Hn(){function se(){Hn()}if(document.readyState==="loading"){$n||window.addEventListener("DOMContentLoaded",se,!1),$n=!0;return}document.querySelectorAll(Se.cssSelector).forEach(je)}function Ot(se,Pe){let nt=null;try{nt=Pe(N)}catch(St){if(ne("Language definition for '{}' could not be registered.".replace("{}",se)),it)ne(St);else throw St;nt=ce}nt.name||(nt.name=se),V[se]=nt,nt.rawDefinition=Pe.bind(null,N),nt.aliases&&Sr(nt.aliases,{languageName:se})}function pn(se){delete V[se];for(const Pe of Object.keys(re))re[Pe]===se&&delete re[Pe]}function Zn(){return Object.keys(V)}function vt(se){return se=(se||"").toLowerCase(),V[se]||V[re[se]]}function Sr(se,{languageName:Pe}){typeof se=="string"&&(se=[se]),se.forEach(nt=>{re[nt.toLowerCase()]=Pe})}function Ei(se){const Pe=vt(se);return Pe&&!Pe.disableAutodetect}function v_(se){se["before:highlightBlock"]&&!se["before:highlightElement"]&&(se["before:highlightElement"]=Pe=>{se["before:highlightBlock"](Object.assign({block:Pe.el},Pe))}),se["after:highlightBlock"]&&!se["after:highlightElement"]&&(se["after:highlightElement"]=Pe=>{se["after:highlightBlock"](Object.assign({block:Pe.el},Pe))})}function R_(se){v_(se),Ie.push(se)}function C_(se){const Pe=Ie.indexOf(se);Pe!==-1&&Ie.splice(Pe,1)}function Mr(se,Pe){const nt=se;Ie.forEach(function(St){St[nt]&&St[nt](Pe)})}function N_(se){return De("10.7.0","highlightBlock will be removed entirely in v12.0"),De("10.7.0","Please use highlightElement now."),je(se)}Object.assign(N,{highlight:Ge,highlightAuto:In,highlightAll:Hn,highlightElement:je,highlightBlock:N_,configure:yt,initHighlighting:tn,initHighlightingOnLoad:sn,registerLanguage:Ot,unregisterLanguage:pn,listLanguages:Zn,getLanguage:vt,registerAliases:Sr,autoDetection:Ei,inherit:W,addPlugin:R_,removePlugin:C_}),N.debugMode=function(){it=!1},N.safeMode=function(){it=!0},N.versionString=ye,N.regex={concat:E,lookahead:u,either:b,optional:p,anyNumberOfTimes:m};for(const se in O)typeof O[se]=="object"&&e(O[se]);return Object.assign(N,O),N},Ue=Ze({});return Ue.newInstance=()=>Ze({}),Ui=Ue,Ue.HighlightJS=Ue,Ue.default=Ue,Ui}var Fi,kd;function dv(){if(kd)return Fi;kd=1;function e(t){const n="[A-Za-zА-Яа-яёЁ_][A-Za-zА-Яа-яёЁ_0-9]+",i="далее "+"возврат вызватьисключение выполнить для если и из или иначе иначеесли исключение каждого конецесли конецпопытки конеццикла не новый перейти перем по пока попытка прервать продолжить тогда цикл экспорт ",c="загрузитьизфайла "+"вебклиент вместо внешнеесоединение клиент конецобласти мобильноеприложениеклиент мобильноеприложениесервер наклиенте наклиентенасервере наклиентенасерверебезконтекста насервере насерверебезконтекста область перед после сервер толстыйклиентобычноеприложение толстыйклиентуправляемоеприложение тонкийклиент ",m="разделительстраниц разделительстрок символтабуляции "+"ansitooem oemtoansi ввестивидсубконто ввестиперечисление ввестипериод ввестиплансчетов выбранныйплансчетов датагод датамесяц датачисло заголовоксистемы значениевстроку значениеизстроки каталогиб каталогпользователя кодсимв конгода конецпериодаби конецрассчитанногопериодаби конецстандартногоинтервала конквартала конмесяца коннедели лог лог10 максимальноеколичествосубконто названиеинтерфейса названиенабораправ назначитьвид назначитьсчет найтиссылки началопериодаби началостандартногоинтервала начгода начквартала начмесяца начнедели номерднягода номерднянедели номернеделигода обработкаожидания основнойжурналрасчетов основнойплансчетов основнойязык очиститьокносообщений периодстр получитьвремята получитьдатута получитьдокументта получитьзначенияотбора получитьпозициюта получитьпустоезначение получитьта префиксавтонумерации пропись пустоезначение разм разобратьпозициюдокумента рассчитатьрегистрына рассчитатьрегистрыпо симв создатьобъект статусвозврата стрколичествострок сформироватьпозициюдокумента счетпокоду текущеевремя типзначения типзначениястр установитьтана установитьтапо фиксшаблон шаблон "+"acos asin atan base64значение base64строка cos exp log log10 pow sin sqrt tan xmlзначение xmlстрока xmlтип xmlтипзнч активноеокно безопасныйрежим безопасныйрежимразделенияданных булево ввестидату ввестизначение ввестистроку ввестичисло возможностьчтенияxml вопрос восстановитьзначение врег выгрузитьжурналрегистрации выполнитьобработкуоповещения выполнитьпроверкуправдоступа вычислить год данныеформывзначение дата день деньгода деньнедели добавитьмесяц заблокироватьданныедляредактирования заблокироватьработупользователя завершитьработусистемы загрузитьвнешнююкомпоненту закрытьсправку записатьjson записатьxml записатьдатуjson записьжурналарегистрации заполнитьзначениясвойств запроситьразрешениепользователя запуститьприложение запуститьсистему зафиксироватьтранзакцию значениевданныеформы значениевстрокувнутр значениевфайл значениезаполнено значениеизстрокивнутр значениеизфайла изxmlтипа импортмоделиxdto имякомпьютера имяпользователя инициализироватьпредопределенныеданные информацияобошибке каталогбиблиотекимобильногоустройства каталогвременныхфайлов каталогдокументов каталогпрограммы кодироватьстроку кодлокализацииинформационнойбазы кодсимвола командасистемы конецгода конецдня конецквартала конецмесяца конецминуты конецнедели конецчаса конфигурациябазыданныхизмененадинамически конфигурацияизменена копироватьданныеформы копироватьфайл краткоепредставлениеошибки лев макс местноевремя месяц мин минута монопольныйрежим найти найтинедопустимыесимволыxml найтиокнопонавигационнойссылке найтипомеченныенаудаление найтипоссылкам найтифайлы началогода началодня началоквартала началомесяца началоминуты началонедели началочаса начатьзапросразрешенияпользователя начатьзапускприложения начатькопированиефайла начатьперемещениефайла начатьподключениевнешнейкомпоненты начатьподключениерасширенияработыскриптографией начатьподключениерасширенияработысфайлами начатьпоискфайлов начатьполучениекаталогавременныхфайлов начатьполучениекаталогадокументов начатьполучениерабочегокаталогаданныхпользователя начатьполучениефайлов начатьпомещениефайла начатьпомещениефайлов начатьсозданиедвоичныхданныхизфайла начатьсозданиекаталога начатьтранзакцию начатьудалениефайлов начатьустановкувнешнейкомпоненты начатьустановкурасширенияработыскриптографией начатьустановкурасширенияработысфайлами неделягода необходимостьзавершениясоединения номерсеансаинформационнойбазы номерсоединенияинформационнойбазы нрег нстр обновитьинтерфейс обновитьнумерациюобъектов обновитьповторноиспользуемыезначения обработкапрерыванияпользователя объединитьфайлы окр описаниеошибки оповестить оповеститьобизменении отключитьобработчикзапросанастроекклиенталицензирования отключитьобработчикожидания отключитьобработчикоповещения открытьзначение открытьиндекссправки открытьсодержаниесправки открытьсправку открытьформу открытьформумодально отменитьтранзакцию очиститьжурналрегистрации очиститьнастройкипользователя очиститьсообщения параметрыдоступа перейтипонавигационнойссылке переместитьфайл подключитьвнешнююкомпоненту подключитьобработчикзапросанастроекклиенталицензирования подключитьобработчикожидания подключитьобработчикоповещения подключитьрасширениеработыскриптографией подключитьрасширениеработысфайлами подробноепредставлениеошибки показатьвводдаты показатьвводзначения показатьвводстроки показатьвводчисла показатьвопрос показатьзначение показатьинформациюобошибке показатьнакарте показатьоповещениепользователя показатьпредупреждение полноеимяпользователя получитьcomобъект получитьxmlтип получитьадреспоместоположению получитьблокировкусеансов получитьвремязавершенияспящегосеанса получитьвремязасыпанияпассивногосеанса получитьвремяожиданияблокировкиданных получитьданныевыбора получитьдополнительныйпараметрклиенталицензирования получитьдопустимыекодылокализации получитьдопустимыечасовыепояса получитьзаголовокклиентскогоприложения получитьзаголовоксистемы получитьзначенияотборажурналарегистрации получитьидентификаторконфигурации получитьизвременногохранилища получитьимявременногофайла получитьимяклиенталицензирования получитьинформациюэкрановклиента получитьиспользованиежурналарегистрации получитьиспользованиесобытияжурналарегистрации получитькраткийзаголовокприложения получитьмакетоформления получитьмаскувсефайлы получитьмаскувсефайлыклиента получитьмаскувсефайлысервера получитьместоположениепоадресу получитьминимальнуюдлинупаролейпользователей получитьнавигационнуюссылку получитьнавигационнуюссылкуинформационнойбазы получитьобновлениеконфигурациибазыданных получитьобновлениепредопределенныхданныхинформационнойбазы получитьобщиймакет получитьобщуюформу получитьокна получитьоперативнуюотметкувремени получитьотключениебезопасногорежима получитьпараметрыфункциональныхопцийинтерфейса получитьполноеимяпредопределенногозначения получитьпредставлениянавигационныхссылок получитьпроверкусложностипаролейпользователей получитьразделительпути получитьразделительпутиклиента получитьразделительпутисервера получитьсеансыинформационнойбазы получитьскоростьклиентскогосоединения получитьсоединенияинформационнойбазы получитьсообщенияпользователю получитьсоответствиеобъектаиформы получитьсоставстандартногоинтерфейсаodata получитьструктурухранениябазыданных получитьтекущийсеансинформационнойбазы получитьфайл получитьфайлы получитьформу получитьфункциональнуюопцию получитьфункциональнуюопциюинтерфейса получитьчасовойпоясинформационнойбазы пользователиос поместитьвовременноехранилище поместитьфайл поместитьфайлы прав праводоступа предопределенноезначение представлениекодалокализации представлениепериода представлениеправа представлениеприложения представлениесобытияжурналарегистрации представлениечасовогопояса предупреждение прекратитьработусистемы привилегированныйрежим продолжитьвызов прочитатьjson прочитатьxml прочитатьдатуjson пустаястрока рабочийкаталогданныхпользователя разблокироватьданныедляредактирования разделитьфайл разорватьсоединениесвнешнимисточникомданных раскодироватьстроку рольдоступна секунда сигнал символ скопироватьжурналрегистрации смещениелетнеговремени смещениестандартноговремени соединитьбуферыдвоичныхданных создатькаталог создатьфабрикуxdto сокрл сокрлп сокрп сообщить состояние сохранитьзначение сохранитьнастройкипользователя сред стрдлина стрзаканчиваетсяна стрзаменить стрнайти стрначинаетсяс строка строкасоединенияинформационнойбазы стрполучитьстроку стрразделить стрсоединить стрсравнить стрчисловхождений стрчислострок стршаблон текущаядата текущаядатасеанса текущаяуниверсальнаядата текущаяуниверсальнаядатавмиллисекундах текущийвариантинтерфейсаклиентскогоприложения текущийвариантосновногошрифтаклиентскогоприложения текущийкодлокализации текущийрежимзапуска текущийязык текущийязыксистемы тип типзнч транзакцияактивна трег удалитьданныеинформационнойбазы удалитьизвременногохранилища удалитьобъекты удалитьфайлы универсальноевремя установитьбезопасныйрежим установитьбезопасныйрежимразделенияданных установитьблокировкусеансов установитьвнешнююкомпоненту установитьвремязавершенияспящегосеанса установитьвремязасыпанияпассивногосеанса установитьвремяожиданияблокировкиданных установитьзаголовокклиентскогоприложения установитьзаголовоксистемы установитьиспользованиежурналарегистрации установитьиспользованиесобытияжурналарегистрации установитькраткийзаголовокприложения установитьминимальнуюдлинупаролейпользователей установитьмонопольныйрежим установитьнастройкиклиенталицензирования установитьобновлениепредопределенныхданныхинформационнойбазы установитьотключениебезопасногорежима установитьпараметрыфункциональныхопцийинтерфейса установитьпривилегированныйрежим установитьпроверкусложностипаролейпользователей установитьрасширениеработыскриптографией установитьрасширениеработысфайлами установитьсоединениесвнешнимисточникомданных установитьсоответствиеобъектаиформы установитьсоставстандартногоинтерфейсаodata установитьчасовойпоясинформационнойбазы установитьчасовойпояссеанса формат цел час часовойпояс часовойпояссеанса число числопрописью этоадресвременногохранилища "+"wsссылки библиотекакартинок библиотекамакетовоформлениякомпоновкиданных библиотекастилей бизнеспроцессы внешниеисточникиданных внешниеобработки внешниеотчеты встроенныепокупки главныйинтерфейс главныйстиль документы доставляемыеуведомления журналыдокументов задачи информацияобинтернетсоединении использованиерабочейдаты историяработыпользователя константы критерииотбора метаданные обработки отображениерекламы отправкадоставляемыхуведомлений отчеты панельзадачос параметрзапуска параметрысеанса перечисления планывидоврасчета планывидовхарактеристик планыобмена планысчетов полнотекстовыйпоиск пользователиинформационнойбазы последовательности проверкавстроенныхпокупок рабочаядата расширенияконфигурации регистрыбухгалтерии регистрынакопления регистрырасчета регистрысведений регламентныезадания сериализаторxdto справочники средствагеопозиционирования средствакриптографии средствамультимедиа средстваотображениярекламы средствапочты средствателефонии фабрикаxdto файловыепотоки фоновыезадания хранилищанастроек хранилищевариантовотчетов хранилищенастроекданныхформ хранилищеобщихнастроек хранилищепользовательскихнастроекдинамическихсписков хранилищепользовательскихнастроекотчетов хранилищесистемныхнастроек ",Le="webцвета windowsцвета windowsшрифты библиотекакартинок рамкистиля символы цветастиля шрифтыстиля "+"автоматическоесохранениеданныхформывнастройках автонумерациявформе автораздвижениесерий анимациядиаграммы вариантвыравниванияэлементовизаголовков вариантуправлениявысотойтаблицы вертикальнаяпрокруткаформы вертикальноеположение вертикальноеположениеэлемента видгруппыформы виддекорацииформы виддополненияэлементаформы видизмененияданных видкнопкиформы видпереключателя видподписейкдиаграмме видполяформы видфлажка влияниеразмеранапузырекдиаграммы горизонтальноеположение горизонтальноеположениеэлемента группировкаколонок группировкаподчиненныхэлементовформы группыиэлементы действиеперетаскивания дополнительныйрежимотображения допустимыедействияперетаскивания интервалмеждуэлементамиформы использованиевывода использованиеполосыпрокрутки используемоезначениеточкибиржевойдиаграммы историявыборапривводе источникзначенийоситочекдиаграммы источникзначенияразмерапузырькадиаграммы категориягруппыкоманд максимумсерий начальноеотображениедерева начальноеотображениесписка обновлениетекстаредактирования ориентациядендрограммы ориентациядиаграммы ориентацияметокдиаграммы ориентацияметоксводнойдиаграммы ориентацияэлементаформы отображениевдиаграмме отображениевлегендедиаграммы отображениегруппыкнопок отображениезаголовкашкалыдиаграммы отображениезначенийсводнойдиаграммы отображениезначенияизмерительнойдиаграммы отображениеинтерваладиаграммыганта отображениекнопки отображениекнопкивыбора отображениеобсужденийформы отображениеобычнойгруппы отображениеотрицательныхзначенийпузырьковойдиаграммы отображениепанелипоиска отображениеподсказки отображениепредупрежденияприредактировании отображениеразметкиполосырегулирования отображениестраницформы отображениетаблицы отображениетекстазначениядиаграммыганта отображениеуправленияобычнойгруппы отображениефигурыкнопки палитрацветовдиаграммы поведениеобычнойгруппы поддержкамасштабадендрограммы поддержкамасштабадиаграммыганта поддержкамасштабасводнойдиаграммы поисквтаблицепривводе положениезаголовкаэлементаформы положениекартинкикнопкиформы положениекартинкиэлементаграфическойсхемы положениекоманднойпанелиформы положениекоманднойпанелиэлементаформы положениеопорнойточкиотрисовки положениеподписейкдиаграмме положениеподписейшкалызначенийизмерительнойдиаграммы положениесостоянияпросмотра положениестрокипоиска положениетекстасоединительнойлинии положениеуправленияпоиском положениешкалывремени порядокотображенияточекгоризонтальнойгистограммы порядоксерийвлегендедиаграммы размеркартинки расположениезаголовкашкалыдиаграммы растягиваниеповертикалидиаграммыганта режимавтоотображениясостояния режимвводастроктаблицы режимвыборанезаполненного режимвыделениядаты режимвыделениястрокитаблицы режимвыделениятаблицы режимизмененияразмера режимизменениясвязанногозначения режимиспользованиядиалогапечати режимиспользованияпараметракоманды режиммасштабированияпросмотра режимосновногоокнаклиентскогоприложения режимоткрытияокнаформы режимотображениявыделения режимотображениягеографическойсхемы режимотображениязначенийсерии режимотрисовкисеткиграфическойсхемы режимполупрозрачностидиаграммы режимпробеловдиаграммы режимразмещениянастранице режимредактированияколонки режимсглаживаниядиаграммы режимсглаживанияиндикатора режимсписказадач сквозноевыравнивание сохранениеданныхформывнастройках способзаполнениятекстазаголовкашкалыдиаграммы способопределенияограничивающегозначениядиаграммы стандартнаягруппакоманд стандартноеоформление статусоповещенияпользователя стильстрелки типаппроксимациилиниитрендадиаграммы типдиаграммы типединицышкалывремени типимпортасерийслоягеографическойсхемы типлиниигеографическойсхемы типлиниидиаграммы типмаркерагеографическойсхемы типмаркерадиаграммы типобластиоформления типорганизацииисточникаданныхгеографическойсхемы типотображениясериислоягеографическойсхемы типотображенияточечногообъектагеографическойсхемы типотображенияшкалыэлементалегендыгеографическойсхемы типпоискаобъектовгеографическойсхемы типпроекциигеографическойсхемы типразмещенияизмерений типразмещенияреквизитовизмерений типрамкиэлементауправления типсводнойдиаграммы типсвязидиаграммыганта типсоединениязначенийпосериямдиаграммы типсоединенияточекдиаграммы типсоединительнойлинии типстороныэлементаграфическойсхемы типформыотчета типшкалырадарнойдиаграммы факторлиниитрендадиаграммы фигуракнопки фигурыграфическойсхемы фиксациявтаблице форматдняшкалывремени форматкартинки ширинаподчиненныхэлементовформы "+"виддвижениябухгалтерии виддвижениянакопления видпериодарегистрарасчета видсчета видточкимаршрутабизнеспроцесса использованиеагрегатарегистранакопления использованиегруппиэлементов использованиережимапроведения использованиесреза периодичностьагрегатарегистранакопления режимавтовремя режимзаписидокумента режимпроведениядокумента "+"авторегистрацияизменений допустимыйномерсообщения отправкаэлементаданных получениеэлементаданных "+"использованиерасшифровкитабличногодокумента ориентациястраницы положениеитоговколоноксводнойтаблицы положениеитоговстроксводнойтаблицы положениетекстаотносительнокартинки расположениезаголовкагруппировкитабличногодокумента способчтениязначенийтабличногодокумента типдвустороннейпечати типзаполненияобластитабличногодокумента типкурсоровтабличногодокумента типлиниирисункатабличногодокумента типлинииячейкитабличногодокумента типнаправленияпереходатабличногодокумента типотображениявыделениятабличногодокумента типотображениялинийсводнойтаблицы типразмещениятекстатабличногодокумента типрисункатабличногодокумента типсмещениятабличногодокумента типузоратабличногодокумента типфайлатабличногодокумента точностьпечати чередованиерасположениястраниц "+"отображениевремениэлементовпланировщика "+"типфайлаформатированногодокумента "+"обходрезультатазапроса типзаписизапроса "+"видзаполнениярасшифровкипостроителяотчета типдобавленияпредставлений типизмеренияпостроителяотчета типразмещенияитогов "+"доступкфайлу режимдиалогавыборафайла режимоткрытияфайла "+"типизмеренияпостроителязапроса "+"видданныханализа методкластеризации типединицыинтервалавременианализаданных типзаполнениятаблицырезультатаанализаданных типиспользованиячисловыхзначенийанализаданных типисточникаданныхпоискаассоциаций типколонкианализаданныхдереворешений типколонкианализаданныхкластеризация типколонкианализаданныхобщаястатистика типколонкианализаданныхпоискассоциаций типколонкианализаданныхпоискпоследовательностей типколонкимоделипрогноза типмерырасстоянияанализаданных типотсеченияправилассоциации типполяанализаданных типстандартизациианализаданных типупорядочиванияправилассоциациианализаданных типупорядочиванияшаблоновпоследовательностейанализаданных типупрощениядереварешений "+"wsнаправлениепараметра вариантxpathxs вариантзаписидатыjson вариантпростоготипаxs видгруппымоделиxs видфасетаxdto действиепостроителяdom завершенностьпростоготипаxs завершенностьсоставноготипаxs завершенностьсхемыxs запрещенныеподстановкиxs исключениягруппподстановкиxs категорияиспользованияатрибутаxs категорияограниченияидентичностиxs категорияограниченияпространствименxs методнаследованияxs модельсодержимогоxs назначениетипаxml недопустимыеподстановкиxs обработкапробельныхсимволовxs обработкасодержимогоxs ограничениезначенияxs параметрыотбораузловdom переносстрокjson позициявдокументеdom пробельныесимволыxml типатрибутаxml типзначенияjson типканоническогоxml типкомпонентыxs типпроверкиxml типрезультатаdomxpath типузлаdom типузлаxml формаxml формапредставленияxs форматдатыjson экранированиесимволовjson "+"видсравнениякомпоновкиданных действиеобработкирасшифровкикомпоновкиданных направлениесортировкикомпоновкиданных расположениевложенныхэлементоврезультатакомпоновкиданных расположениеитоговкомпоновкиданных расположениегруппировкикомпоновкиданных расположениеполейгруппировкикомпоновкиданных расположениеполякомпоновкиданных расположениереквизитовкомпоновкиданных расположениересурсовкомпоновкиданных типбухгалтерскогоостаткакомпоновкиданных типвыводатекстакомпоновкиданных типгруппировкикомпоновкиданных типгруппыэлементовотборакомпоновкиданных типдополненияпериодакомпоновкиданных типзаголовкаполейкомпоновкиданных типмакетагруппировкикомпоновкиданных типмакетаобластикомпоновкиданных типостаткакомпоновкиданных типпериодакомпоновкиданных типразмещениятекстакомпоновкиданных типсвязинаборовданныхкомпоновкиданных типэлементарезультатакомпоновкиданных расположениелегендыдиаграммыкомпоновкиданных типпримененияотборакомпоновкиданных режимотображенияэлементанастройкикомпоновкиданных режимотображениянастроеккомпоновкиданных состояниеэлементанастройкикомпоновкиданных способвосстановлениянастроеккомпоновкиданных режимкомпоновкирезультата использованиепараметракомпоновкиданных автопозицияресурсовкомпоновкиданных вариантиспользованиягруппировкикомпоновкиданных расположениересурсоввдиаграммекомпоновкиданных фиксациякомпоновкиданных использованиеусловногооформлениякомпоновкиданных "+"важностьинтернетпочтовогосообщения обработкатекстаинтернетпочтовогосообщения способкодированияинтернетпочтовоговложения способкодированиянеasciiсимволовинтернетпочтовогосообщения типтекстапочтовогосообщения протоколинтернетпочты статусразборапочтовогосообщения "+"режимтранзакциизаписижурналарегистрации статустранзакциизаписижурналарегистрации уровеньжурналарегистрации "+"расположениехранилищасертификатовкриптографии режимвключениясертификатовкриптографии режимпроверкисертификатакриптографии типхранилищасертификатовкриптографии "+"кодировкаименфайловвzipфайле методсжатияzip методшифрованияzip режимвосстановленияпутейфайловzip режимобработкиподкаталоговzip режимсохраненияпутейzip уровеньсжатияzip "+"звуковоеоповещение направлениепереходакстроке позициявпотоке порядокбайтов режимблокировкиданных режимуправленияблокировкойданных сервисвстроенныхпокупок состояниефоновогозадания типподписчикадоставляемыхуведомлений уровеньиспользованиязащищенногосоединенияftp "+"направлениепорядкасхемызапроса типдополненияпериодамисхемызапроса типконтрольнойточкисхемызапроса типобъединениясхемызапроса типпараметрадоступнойтаблицысхемызапроса типсоединениясхемызапроса "+"httpметод автоиспользованиеобщегореквизита автопрефиксномеразадачи вариантвстроенногоязыка видиерархии видрегистранакопления видтаблицывнешнегоисточникаданных записьдвиженийприпроведении заполнениепоследовательностей индексирование использованиебазыпланавидоврасчета использованиебыстроговыбора использованиеобщегореквизита использованиеподчинения использованиеполнотекстовогопоиска использованиеразделяемыхданныхобщегореквизита использованиереквизита назначениеиспользованияприложения назначениерасширенияконфигурации направлениепередачи обновлениепредопределенныхданных оперативноепроведение основноепредставлениевидарасчета основноепредставлениевидахарактеристики основноепредставлениезадачи основноепредставлениепланаобмена основноепредставлениесправочника основноепредставлениесчета перемещениеграницыприпроведении периодичностьномерабизнеспроцесса периодичностьномерадокумента периодичностьрегистрарасчета периодичностьрегистрасведений повторноеиспользованиевозвращаемыхзначений полнотекстовыйпоискпривводепостроке принадлежностьобъекта проведение разделениеаутентификацииобщегореквизита разделениеданныхобщегореквизита разделениерасширенийконфигурацииобщегореквизита режимавтонумерацииобъектов режимзаписирегистра режимиспользованиямодальности режимиспользованиясинхронныхвызововрасширенийплатформыивнешнихкомпонент режимповторногоиспользованиясеансов режимполученияданныхвыборапривводепостроке режимсовместимости режимсовместимостиинтерфейса режимуправленияблокировкойданныхпоумолчанию сериикодовпланавидовхарактеристик сериикодовпланасчетов сериикодовсправочника созданиепривводе способвыбора способпоискастрокипривводепостроке способредактирования типданныхтаблицывнешнегоисточникаданных типкодапланавидоврасчета типкодасправочника типмакета типномерабизнеспроцесса типномерадокумента типномеразадачи типформы удалениедвижений "+"важностьпроблемыприменениярасширенияконфигурации вариантинтерфейсаклиентскогоприложения вариантмасштабаформклиентскогоприложения вариантосновногошрифтаклиентскогоприложения вариантстандартногопериода вариантстандартнойдатыначала видграницы видкартинки видотображенияполнотекстовогопоиска видрамки видсравнения видцвета видчисловогозначения видшрифта допустимаядлина допустимыйзнак использованиеbyteordermark использованиеметаданныхполнотекстовогопоиска источникрасширенийконфигурации клавиша кодвозвратадиалога кодировкаxbase кодировкатекста направлениепоиска направлениесортировки обновлениепредопределенныхданных обновлениеприизмененииданных отображениепанелиразделов проверказаполнения режимдиалогавопрос режимзапускаклиентскогоприложения режимокругления режимоткрытияформприложения режимполнотекстовогопоиска скоростьклиентскогосоединения состояниевнешнегоисточникаданных состояниеобновленияконфигурациибазыданных способвыборасертификатаwindows способкодированиястроки статуссообщения типвнешнейкомпоненты типплатформы типповеденияклавишиenter типэлементаинформацииовыполненииобновленияконфигурациибазыданных уровеньизоляциитранзакций хешфункция частидаты",Tt="comобъект ftpсоединение httpзапрос httpсервисответ httpсоединение wsопределения wsпрокси xbase анализданных аннотацияxs блокировкаданных буфердвоичныхданных включениеxs выражениекомпоновкиданных генераторслучайныхчисел географическаясхема географическиекоординаты графическаясхема группамоделиxs данныерасшифровкикомпоновкиданных двоичныеданные дендрограмма диаграмма диаграммаганта диалогвыборафайла диалогвыборацвета диалогвыборашрифта диалограсписаниярегламентногозадания диалогредактированиястандартногопериода диапазон документdom документhtml документацияxs доставляемоеуведомление записьdom записьfastinfoset записьhtml записьjson записьxml записьzipфайла записьданных записьтекста записьузловdom запрос защищенноесоединениеopenssl значенияполейрасшифровкикомпоновкиданных извлечениетекста импортxs интернетпочта интернетпочтовоесообщение интернетпочтовыйпрофиль интернетпрокси интернетсоединение информациядляприложенияxs использованиеатрибутаxs использованиесобытияжурналарегистрации источникдоступныхнастроеккомпоновкиданных итераторузловdom картинка квалификаторыдаты квалификаторыдвоичныхданных квалификаторыстроки квалификаторычисла компоновщикмакетакомпоновкиданных компоновщикнастроеккомпоновкиданных конструктормакетаоформлениякомпоновкиданных конструкторнастроеккомпоновкиданных конструкторформатнойстроки линия макеткомпоновкиданных макетобластикомпоновкиданных макетоформлениякомпоновкиданных маскаxs менеджеркриптографии наборсхемxml настройкикомпоновкиданных настройкисериализацииjson обработкакартинок обработкарасшифровкикомпоновкиданных обходдереваdom объявлениеатрибутаxs объявлениенотацииxs объявлениеэлементаxs описаниеиспользованиясобытиядоступжурналарегистрации описаниеиспользованиясобытияотказвдоступежурналарегистрации описаниеобработкирасшифровкикомпоновкиданных описаниепередаваемогофайла описаниетипов определениегруппыатрибутовxs определениегруппымоделиxs определениеограниченияидентичностиxs определениепростоготипаxs определениесоставноготипаxs определениетипадокументаdom определенияxpathxs отборкомпоновкиданных пакетотображаемыхдокументов параметрвыбора параметркомпоновкиданных параметрызаписиjson параметрызаписиxml параметрычтенияxml переопределениеxs планировщик полеанализаданных полекомпоновкиданных построительdom построительзапроса построительотчета построительотчетаанализаданных построительсхемxml поток потоквпамяти почта почтовоесообщение преобразованиеxsl преобразованиекканоническомуxml процессорвыводарезультатакомпоновкиданныхвколлекциюзначений процессорвыводарезультатакомпоновкиданныхвтабличныйдокумент процессоркомпоновкиданных разыменовательпространствименdom рамка расписаниерегламентногозадания расширенноеимяxml результатчтенияданных своднаядиаграмма связьпараметравыбора связьпотипу связьпотипукомпоновкиданных сериализаторxdto сертификатклиентаwindows сертификатклиентафайл сертификаткриптографии сертификатыудостоверяющихцентровwindows сертификатыудостоверяющихцентровфайл сжатиеданных системнаяинформация сообщениепользователю сочетаниеклавиш сравнениезначений стандартнаядатаначала стандартныйпериод схемаxml схемакомпоновкиданных табличныйдокумент текстовыйдокумент тестируемоеприложение типданныхxml уникальныйидентификатор фабрикаxdto файл файловыйпоток фасетдлиныxs фасетколичестваразрядовдробнойчастиxs фасетмаксимальноговключающегозначенияxs фасетмаксимальногоисключающегозначенияxs фасетмаксимальнойдлиныxs фасетминимальноговключающегозначенияxs фасетминимальногоисключающегозначенияxs фасетминимальнойдлиныxs фасетобразцаxs фасетобщегоколичестваразрядовxs фасетперечисленияxs фасетпробельныхсимволовxs фильтрузловdom форматированнаястрока форматированныйдокумент фрагментxs хешированиеданных хранилищезначения цвет чтениеfastinfoset чтениеhtml чтениеjson чтениеxml чтениеzipфайла чтениеданных чтениетекста чтениеузловdom шрифт элементрезультатакомпоновкиданных "+"comsafearray деревозначений массив соответствие списокзначений структура таблицазначений фиксированнаяструктура фиксированноесоответствие фиксированныймассив ",Et="null истина ложь неопределено",st=t.inherit(t.NUMBER_MODE),Qe={className:"string",begin:'"|\\|',end:'"|$',contains:[{begin:'""'}]},F={begin:"'",end:"'",excludeBegin:!0,excludeEnd:!0,contains:[{className:"number",begin:"\\d{4}([\\.\\\\/:-]?\\d{2}){0,5}"}]},z={match:/[;()+\-:=,]/,className:"punctuation",relevance:0},de=t.inherit(t.C_LINE_COMMENT_MODE),O={className:"meta",begin:"#|&",end:"$",keywords:{$pattern:n,keyword:i+c},contains:[de]},G={className:"symbol",begin:"~",end:";|:",excludeEnd:!0},g={className:"function",variants:[{begin:"процедура|функция",end:"\\)",keywords:"процедура функция"},{begin:"конецпроцедуры|конецфункции",keywords:"конецпроцедуры конецфункции"}],contains:[{begin:"\\(",end:"\\)",endsParent:!0,contains:[{className:"params",begin:n,end:",",excludeEnd:!0,endsWithParent:!0,keywords:{$pattern:n,keyword:"знач",literal:Et},contains:[st,Qe,F]},de]},t.inherit(t.TITLE_MODE,{begin:n})]};return{name:"1C:Enterprise",case_insensitive:!0,keywords:{$pattern:n,keyword:i,built_in:m,class:Le,type:Tt,literal:Et},contains:[O,g,de,G,st,Qe,F,z]}}return Fi=e,Fi}var Bi,Ud;function uv(){if(Ud)return Bi;Ud=1;function e(t){const n=t.regex,r=/^[a-zA-Z][a-zA-Z0-9-]*/,a=["ALPHA","BIT","CHAR","CR","CRLF","CTL","DIGIT","DQUOTE","HEXDIG","HTAB","LF","LWSP","OCTET","SP","VCHAR","WSP"],i=t.COMMENT(/;/,/$/),o={scope:"symbol",match:/%b[0-1]+(-[0-1]+|(\.[0-1]+)+)?/},s={scope:"symbol",match:/%d[0-9]+(-[0-9]+|(\.[0-9]+)+)?/},c={scope:"symbol",match:/%x[0-9A-F]+(-[0-9A-F]+|(\.[0-9A-F]+)+)?/},l={scope:"symbol",match:/%[si](?=".*")/},_={scope:"attribute",match:n.concat(r,/(?=\s*=)/)};return{name:"Augmented Backus-Naur Form",illegal:/[!@#$^&',?+~`|:]/,keywords:a,contains:[{scope:"operator",match:/=\/?/},_,i,o,s,c,l,t.QUOTE_STRING_MODE,t.NUMBER_MODE]}}return Bi=e,Bi}var Gi,Fd;function pv(){if(Fd)return Gi;Fd=1;function e(t){const n=t.regex,r=["GET","POST","HEAD","PUT","DELETE","CONNECT","OPTIONS","PATCH","TRACE"];return{name:"Apache Access Log",contains:[{className:"number",begin:/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(:\d{1,5})?\b/,relevance:5},{className:"number",begin:/\b\d+\b/,relevance:0},{className:"string",begin:n.concat(/"/,n.either(...r)),end:/"/,keywords:r,illegal:/\n/,relevance:5,contains:[{begin:/HTTP\/[12]\.\d'/,relevance:5}]},{className:"string",begin:/\[\d[^\]\n]{8,}\]/,illegal:/\n/,relevance:1},{className:"string",begin:/\[/,end:/\]/,illegal:/\n/,relevance:0},{className:"string",begin:/"Mozilla\/\d\.\d \(/,end:/"/,illegal:/\n/,relevance:3},{className:"string",begin:/"/,end:/"/,illegal:/\n/,relevance:0}]}}return Gi=e,Gi}var Yi,Bd;function mv(){if(Bd)return Yi;Bd=1;function e(t){const n=t.regex,r=/[a-zA-Z_$][a-zA-Z0-9_$]*/,a=n.concat(r,n.concat("(\\.",r,")*")),i=/([*]|[a-zA-Z_$][a-zA-Z0-9_$]*)/,o={className:"rest_arg",begin:/[.]{3}/,end:r,relevance:10};return{name:"ActionScript",aliases:["as"],keywords:{keyword:["as","break","case","catch","class","const","continue","default","delete","do","dynamic","each","else","extends","final","finally","for","function","get","if","implements","import","in","include","instanceof","interface","internal","is","namespace","native","new","override","package","private","protected","public","return","set","static","super","switch","this","throw","try","typeof","use","var","void","while","with"],literal:["true","false","null","undefined"]},contains:[t.APOS_STRING_MODE,t.QUOTE_STRING_MODE,t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE,t.C_NUMBER_MODE,{match:[/\bpackage/,/\s+/,a],className:{1:"keyword",3:"title.class"}},{match:[/\b(?:class|interface|extends|implements)/,/\s+/,r],className:{1:"keyword",3:"title.class"}},{className:"meta",beginKeywords:"import include",end:/;/,keywords:{keyword:"import include"}},{beginKeywords:"function",end:/[{;]/,excludeEnd:!0,illegal:/\S/,contains:[t.inherit(t.TITLE_MODE,{className:"title.function"}),{className:"params",begin:/\(/,end:/\)/,contains:[t.APOS_STRING_MODE,t.QUOTE_STRING_MODE,t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE,o]},{begin:n.concat(/:\s*/,i)}]},t.METHOD_GUARD],illegal:/#/}}return Yi=e,Yi}var qi,Gd;function gv(){if(Gd)return qi;Gd=1;function e(t){const n="\\d(_|\\d)*",r="[eE][-+]?"+n,a=n+"(\\."+n+")?("+r+")?",i="\\w+",s="\\b("+(n+"#"+i+"(\\."+i+")?#("+r+")?")+"|"+a+")",c="[A-Za-z](_?[A-Za-z0-9.])*",l=`[]\\{\\}%#'"`,_=t.COMMENT("--","$"),d={begin:"\\s+:\\s+",end:"\\s*(:=|;|\\)|=>|$)",illegal:l,contains:[{beginKeywords:"loop for declare others",endsParent:!0},{className:"keyword",beginKeywords:"not null constant access function procedure in out aliased exception"},{className:"type",begin:c,endsParent:!0,relevance:0}]};return{name:"Ada",case_insensitive:!0,keywords:{keyword:["abort","else","new","return","abs","elsif","not","reverse","abstract","end","accept","entry","select","access","exception","of","separate","aliased","exit","or","some","all","others","subtype","and","for","out","synchronized","array","function","overriding","at","tagged","generic","package","task","begin","goto","pragma","terminate","body","private","then","if","procedure","type","case","in","protected","constant","interface","is","raise","use","declare","range","delay","limited","record","when","delta","loop","rem","while","digits","renames","with","do","mod","requeue","xor"],literal:["True","False"]},contains:[_,{className:"string",begin:/"/,end:/"/,contains:[{begin:/""/,relevance:0}]},{className:"string",begin:/'.'/},{className:"number",begin:s,relevance:0},{className:"symbol",begin:"'"+c},{className:"title",begin:"(\\bwith\\s+)?(\\bprivate\\s+)?\\bpackage\\s+(\\bbody\\s+)?",end:"(is|$)",keywords:"package body",excludeBegin:!0,excludeEnd:!0,illegal:l},{begin:"(\\b(with|overriding)\\s+)?\\b(function|procedure)\\s+",end:"(\\bis|\\bwith|\\brenames|\\)\\s*;)",keywords:"overriding function procedure with is renames return",returnBegin:!0,contains:[_,{className:"title",begin:"(\\bwith\\s+)?\\b(function|procedure)\\s+",end:"(\\(|\\s+|$)",excludeBegin:!0,excludeEnd:!0,illegal:l},d,{className:"type",begin:"\\breturn\\s+",end:"(\\s+|;|$)",keywords:"return",excludeBegin:!0,excludeEnd:!0,endsParent:!0,illegal:l}]},{className:"type",begin:"\\b(sub)?type\\s+",end:"\\s+",keywords:"type",excludeBegin:!0,illegal:l},d]}}return qi=e,qi}var $i,Yd;function Ev(){if(Yd)return $i;Yd=1;function e(t){const n={className:"built_in",begin:"\\b(void|bool|int8|int16|int32|int64|int|uint8|uint16|uint32|uint64|uint|string|ref|array|double|float|auto|dictionary)"},r={className:"symbol",begin:"[a-zA-Z0-9_]+@"},a={className:"keyword",begin:"<",end:">",contains:[n,r]};return n.contains=[a],r.contains=[a],{name:"AngelScript",aliases:["asc"],keywords:["for","in|0","break","continue","while","do|0","return","if","else","case","switch","namespace","is","cast","or","and","xor","not","get|0","in","inout|10","out","override","set|0","private","public","const","default|0","final","shared","external","mixin|10","enum","typedef","funcdef","this","super","import","from","interface","abstract|0","try","catch","protected","explicit","property"],illegal:"(^using\\s+[A-Za-z0-9_\\.]+;$|\\bfunction\\s*[^\\(])",contains:[{className:"string",begin:"'",end:"'",illegal:"\\n",contains:[t.BACKSLASH_ESCAPE],relevance:0},{className:"string",begin:'"""',end:'"""'},{className:"string",begin:'"',end:'"',illegal:"\\n",contains:[t.BACKSLASH_ESCAPE],relevance:0},t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE,{className:"string",begin:"^\\s*\\[",end:"\\]"},{beginKeywords:"interface namespace",end:/\{/,illegal:"[;.\\-]",contains:[{className:"symbol",begin:"[a-zA-Z0-9_]+"}]},{beginKeywords:"class",end:/\{/,illegal:"[;.\\-]",contains:[{className:"symbol",begin:"[a-zA-Z0-9_]+",contains:[{begin:"[:,]\\s*",contains:[{className:"symbol",begin:"[a-zA-Z0-9_]+"}]}]}]},n,r,{className:"literal",begin:"\\b(null|true|false)"},{className:"number",relevance:0,begin:"(-?)(\\b0[xXbBoOdD][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?f?|\\.\\d+f?)([eE][-+]?\\d+f?)?)"}]}}return $i=e,$i}var Hi,qd;function Sv(){if(qd)return Hi;qd=1;function e(t){const n={className:"number",begin:/[$%]\d+/},r={className:"number",begin:/\b\d+/},a={className:"number",begin:/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(:\d{1,5})?/},i={className:"number",begin:/:\d{1,5}/};return{name:"Apache config",aliases:["apacheconf"],case_insensitive:!0,contains:[t.HASH_COMMENT_MODE,{className:"section",begin:/<\/?/,end:/>/,contains:[a,i,t.inherit(t.QUOTE_STRING_MODE,{relevance:0})]},{className:"attribute",begin:/\w+/,relevance:0,keywords:{_:["order","deny","allow","setenv","rewriterule","rewriteengine","rewritecond","documentroot","sethandler","errordocument","loadmodule","options","header","listen","serverroot","servername"]},starts:{end:/$/,relevance:0,keywords:{literal:"on off all deny allow"},contains:[{scope:"punctuation",match:/\\\n/},{className:"meta",begin:/\s\[/,end:/\]$/},{className:"variable",begin:/[\$%]\{/,end:/\}/,contains:["self",n]},a,r,t.QUOTE_STRING_MODE]}}],illegal:/\S/}}return Hi=e,Hi}var Vi,$d;function fv(){if($d)return Vi;$d=1;function e(t){const n=t.regex,r=t.inherit(t.QUOTE_STRING_MODE,{illegal:null}),a={className:"params",begin:/\(/,end:/\)/,contains:["self",t.C_NUMBER_MODE,r]},i=t.COMMENT(/--/,/$/),o=t.COMMENT(/\(\*/,/\*\)/,{contains:["self",i]}),s=[i,o,t.HASH_COMMENT_MODE],c=[/apart from/,/aside from/,/instead of/,/out of/,/greater than/,/isn't|(doesn't|does not) (equal|come before|come after|contain)/,/(greater|less) than( or equal)?/,/(starts?|ends|begins?) with/,/contained by/,/comes (before|after)/,/a (ref|reference)/,/POSIX (file|path)/,/(date|time) string/,/quoted form/],l=[/clipboard info/,/the clipboard/,/info for/,/list (disks|folder)/,/mount volume/,/path to/,/(close|open for) access/,/(get|set) eof/,/current date/,/do shell script/,/get volume settings/,/random number/,/set volume/,/system attribute/,/system info/,/time to GMT/,/(load|run|store) script/,/scripting components/,/ASCII (character|number)/,/localized string/,/choose (application|color|file|file name|folder|from list|remote application|URL)/,/display (alert|dialog)/];return{name:"AppleScript",aliases:["osascript"],keywords:{keyword:"about above after against and around as at back before beginning behind below beneath beside between but by considering contain contains continue copy div does eighth else end equal equals error every exit fifth first for fourth from front get given global if ignoring in into is it its last local me middle mod my ninth not of on onto or over prop property put ref reference repeat returning script second set seventh since sixth some tell tenth that the|0 then third through thru timeout times to transaction try until where while whose with without",literal:"AppleScript false linefeed return pi quote result space tab true",built_in:"alias application boolean class constant date file integer list number real record string text activate beep count delay launch log offset read round run say summarize write character characters contents day frontmost id item length month name|0 paragraph paragraphs rest reverse running time version weekday word words year"},contains:[r,t.C_NUMBER_MODE,{className:"built_in",begin:n.concat(/\b/,n.either(...l),/\b/)},{className:"built_in",begin:/^\s*return\b/},{className:"literal",begin:/\b(text item delimiters|current application|missing value)\b/},{className:"keyword",begin:n.concat(/\b/,n.either(...c),/\b/)},{beginKeywords:"on",illegal:/[${=;\n]/,contains:[t.UNDERSCORE_TITLE_MODE,a]},...s],illegal:/\/\/|->|=>|\[\[/}}return Vi=e,Vi}var zi,Hd;function bv(){if(Hd)return zi;Hd=1;function e(t){const n=t.regex,r="[A-Za-z_][0-9A-Za-z_]*",a={keyword:["break","case","catch","continue","debugger","do","else","export","for","function","if","import","in","new","of","return","switch","try","var","void","while"],literal:["BackSlash","DoubleQuote","ForwardSlash","Infinity","NaN","NewLine","PI","SingleQuote","Tab","TextFormatting","false","null","true","undefined"],built_in:["Abs","Acos","All","Angle","Any","Area","AreaGeodetic","Array","Asin","Atan","Atan2","Attachments","Average","Back","Bearing","Boolean","Buffer","BufferGeodetic","Ceil","Centroid","ChangeTimeZone","Clip","Concatenate","Console","Constrain","Contains","ConvertDirection","ConvexHull","Cos","Count","Crosses","Cut","Date|0","DateAdd","DateDiff","DateOnly","Day","Decode","DefaultValue","Densify","DensifyGeodetic","Dictionary","Difference","Disjoint","Distance","DistanceGeodetic","DistanceToCoordinate","Distinct","Domain","DomainCode","DomainName","EnvelopeIntersects","Equals","Erase","Exp","Expects","Extent","Feature","FeatureInFilter","FeatureSet","FeatureSetByAssociation","FeatureSetById","FeatureSetByName","FeatureSetByPortalItem","FeatureSetByRelationshipClass","FeatureSetByRelationshipName","Filter","FilterBySubtypeCode","Find","First|0","Floor","FromCharCode","FromCodePoint","FromJSON","Front","GdbVersion","Generalize","Geometry","GetEnvironment","GetFeatureSet","GetFeatureSetInfo","GetUser","GroupBy","Guid","HasKey","HasValue","Hash","Hour","IIf","ISOMonth","ISOWeek","ISOWeekday","ISOYear","Includes","IndexOf","Insert","Intersection","Intersects","IsEmpty","IsNan","IsSelfIntersecting","IsSimple","KnowledgeGraphByPortalItem","Left|0","Length","Length3D","LengthGeodetic","Log","Lower","Map","Max","Mean","MeasureToCoordinate","Mid","Millisecond","Min","Minute","Month","MultiPartToSinglePart","Multipoint","NearestCoordinate","NearestVertex","NextSequenceValue","None","Now","Number","Offset","OrderBy","Overlaps","Point","PointToCoordinate","Polygon","Polyline","Pop","Portal","Pow","Proper","Push","QueryGraph","Random","Reduce","Relate","Replace","Resize","Reverse","Right|0","RingIsClockwise","Rotate","Round","Schema","Second","SetGeometry","Simplify","Sin","Slice","Sort","Splice","Split","Sqrt","StandardizeFilename","StandardizeGuid","Stdev","SubtypeCode","SubtypeName","Subtypes","Sum","SymmetricDifference","Tan","Text","Time","TimeZone","TimeZoneOffset","Timestamp","ToCharCode","ToCodePoint","ToHex","ToLocal","ToUTC","Today","Top|0","Touches","TrackAccelerationAt","TrackAccelerationWindow","TrackCurrentAcceleration","TrackCurrentDistance","TrackCurrentSpeed","TrackCurrentTime","TrackDistanceAt","TrackDistanceWindow","TrackDuration","TrackFieldWindow","TrackGeometryWindow","TrackIndex","TrackSpeedAt","TrackSpeedWindow","TrackStartTime","TrackWindow","Trim","TypeOf","Union","Upper","UrlEncode","Variance","Week","Weekday","When|0","Within","Year|0"]},i=["aggregatedFeatures","analytic","config","datapoint","datastore","editcontext","feature","featureSet","feedfeature","fencefeature","fencenotificationtype","graph","join","layer","locationupdate","map","measure","measure","originalFeature","record","reference","rowindex","sourcedatastore","sourcefeature","sourcelayer","target","targetdatastore","targetfeature","targetlayer","userInput","value","variables","view"],o={className:"symbol",begin:"\\$"+n.either(...i)},s={className:"number",variants:[{begin:"\\b(0[bB][01]+)"},{begin:"\\b(0[oO][0-7]+)"},{begin:t.C_NUMBER_RE}],relevance:0},c={className:"subst",begin:"\\$\\{",end:"\\}",keywords:a,contains:[]},l={className:"string",begin:"`",end:"`",contains:[t.BACKSLASH_ESCAPE,c]};c.contains=[t.APOS_STRING_MODE,t.QUOTE_STRING_MODE,l,s,t.REGEXP_MODE];const _=c.contains.concat([t.C_BLOCK_COMMENT_MODE,t.C_LINE_COMMENT_MODE]);return{name:"ArcGIS Arcade",case_insensitive:!0,keywords:a,contains:[t.APOS_STRING_MODE,t.QUOTE_STRING_MODE,l,t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE,o,s,{begin:/[{,]\s*/,relevance:0,contains:[{begin:r+"\\s*:",returnBegin:!0,relevance:0,contains:[{className:"attr",begin:r,relevance:0}]}]},{begin:"("+t.RE_STARTERS_RE+"|\\b(return)\\b)\\s*",keywords:"return",contains:[t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE,t.REGEXP_MODE,{className:"function",begin:"(\\(.*?\\)|"+r+")\\s*=>",returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:r},{begin:/\(\s*\)/},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:a,contains:_}]}]}],relevance:0},{beginKeywords:"function",end:/\{/,excludeEnd:!0,contains:[t.inherit(t.TITLE_MODE,{className:"title.function",begin:r}),{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,contains:_}],illegal:/\[|%/},{begin:/\$[(.]/}],illegal:/#(?!!)/}}return zi=e,zi}var Wi,Vd;function Tv(){if(Vd)return Wi;Vd=1;function e(n){const r=n.regex,a=n.COMMENT("//","$",{contains:[{begin:/\\\n/}]}),i="decltype\\(auto\\)",o="[a-zA-Z_]\\w*::",c="(?!struct)("+i+"|"+r.optional(o)+"[a-zA-Z_]\\w*"+r.optional("<[^<>]+>")+")",l={className:"type",begin:"\\b[a-z\\d_]*_t\\b"},d={className:"string",variants:[{begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[n.BACKSLASH_ESCAPE]},{begin:"(u8?|U|L)?'("+"\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)"+"|.)",end:"'",illegal:"."},n.END_SAME_AS_BEGIN({begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},u={className:"number",variants:[{begin:"[+-]?(?:(?:[0-9](?:'?[0-9])*\\.(?:[0-9](?:'?[0-9])*)?|\\.[0-9](?:'?[0-9])*)(?:[Ee][+-]?[0-9](?:'?[0-9])*)?|[0-9](?:'?[0-9])*[Ee][+-]?[0-9](?:'?[0-9])*|0[Xx](?:[0-9A-Fa-f](?:'?[0-9A-Fa-f])*(?:\\.(?:[0-9A-Fa-f](?:'?[0-9A-Fa-f])*)?)?|\\.[0-9A-Fa-f](?:'?[0-9A-Fa-f])*)[Pp][+-]?[0-9](?:'?[0-9])*)(?:[Ff](?:16|32|64|128)?|(BF|bf)16|[Ll]|)"},{begin:"[+-]?\\b(?:0[Bb][01](?:'?[01])*|0[Xx][0-9A-Fa-f](?:'?[0-9A-Fa-f])*|0(?:'?[0-7])*|[1-9](?:'?[0-9])*)(?:[Uu](?:LL?|ll?)|[Uu][Zz]?|(?:LL?|ll?)[Uu]?|[Zz][Uu]|)"}],relevance:0},m={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include"},contains:[{begin:/\\\n/,relevance:0},n.inherit(d,{className:"string"}),{className:"string",begin:/<.*?>/},a,n.C_BLOCK_COMMENT_MODE]},p={className:"title",begin:r.optional(o)+n.IDENT_RE,relevance:0},E=r.optional(o)+n.IDENT_RE+"\\s*\\(",S=["alignas","alignof","and","and_eq","asm","atomic_cancel","atomic_commit","atomic_noexcept","auto","bitand","bitor","break","case","catch","class","co_await","co_return","co_yield","compl","concept","const_cast|10","consteval","constexpr","constinit","continue","decltype","default","delete","do","dynamic_cast|10","else","enum","explicit","export","extern","false","final","for","friend","goto","if","import","inline","module","mutable","namespace","new","noexcept","not","not_eq","nullptr","operator","or","or_eq","override","private","protected","public","reflexpr","register","reinterpret_cast|10","requires","return","sizeof","static_assert","static_cast|10","struct","switch","synchronized","template","this","thread_local","throw","transaction_safe","transaction_safe_dynamic","true","try","typedef","typeid","typename","union","using","virtual","volatile","while","xor","xor_eq"],b=["bool","char","char16_t","char32_t","char8_t","double","float","int","long","short","void","wchar_t","unsigned","signed","const","static"],h=["any","auto_ptr","barrier","binary_semaphore","bitset","complex","condition_variable","condition_variable_any","counting_semaphore","deque","false_type","flat_map","flat_set","future","imaginary","initializer_list","istringstream","jthread","latch","lock_guard","multimap","multiset","mutex","optional","ostringstream","packaged_task","pair","promise","priority_queue","queue","recursive_mutex","recursive_timed_mutex","scoped_lock","set","shared_future","shared_lock","shared_mutex","shared_timed_mutex","shared_ptr","stack","string_view","stringstream","timed_mutex","thread","true_type","tuple","unique_lock","unique_ptr","unordered_map","unordered_multimap","unordered_multiset","unordered_set","variant","vector","weak_ptr","wstring","wstring_view"],A=["abort","abs","acos","apply","as_const","asin","atan","atan2","calloc","ceil","cerr","cin","clog","cos","cosh","cout","declval","endl","exchange","exit","exp","fabs","floor","fmod","forward","fprintf","fputs","free","frexp","fscanf","future","invoke","isalnum","isalpha","iscntrl","isdigit","isgraph","islower","isprint","ispunct","isspace","isupper","isxdigit","labs","launder","ldexp","log","log10","make_pair","make_shared","make_shared_for_overwrite","make_tuple","make_unique","malloc","memchr","memcmp","memcpy","memset","modf","move","pow","printf","putchar","puts","realloc","scanf","sin","sinh","snprintf","sprintf","sqrt","sscanf","std","stderr","stdin","stdout","strcat","strchr","strcmp","strcpy","strcspn","strlen","strncat","strncmp","strncpy","strpbrk","strrchr","strspn","strstr","swap","tan","tanh","terminate","to_underlying","tolower","toupper","vfprintf","visit","vprintf","vsprintf"],y={type:b,keyword:S,literal:["NULL","false","nullopt","nullptr","true"],built_in:["_Pragma"],_type_hints:h},I={className:"function.dispatch",relevance:0,keywords:{_hint:A},begin:r.concat(/\b/,/(?!decltype)/,/(?!if)/,/(?!for)/,/(?!switch)/,/(?!while)/,n.IDENT_RE,r.lookahead(/(<[^<>]+>|)\s*\(/))},v=[I,m,l,a,n.C_BLOCK_COMMENT_MODE,u,d],C={variants:[{begin:/=/,end:/;/},{begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}],keywords:y,contains:v.concat([{begin:/\(/,end:/\)/,keywords:y,contains:v.concat(["self"]),relevance:0}]),relevance:0},P={className:"function",begin:"("+c+"[\\*&\\s]+)+"+E,returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:y,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:i,keywords:y,relevance:0},{begin:E,returnBegin:!0,contains:[p],relevance:0},{begin:/::/,relevance:0},{begin:/:/,endsWithParent:!0,contains:[d,u]},{relevance:0,match:/,/},{className:"params",begin:/\(/,end:/\)/,keywords:y,relevance:0,contains:[a,n.C_BLOCK_COMMENT_MODE,d,u,l,{begin:/\(/,end:/\)/,keywords:y,relevance:0,contains:["self",a,n.C_BLOCK_COMMENT_MODE,d,u,l]}]},l,a,n.C_BLOCK_COMMENT_MODE,m]};return{name:"C++",aliases:["cc","c++","h++","hpp","hh","hxx","cxx"],keywords:y,illegal:"",classNameAliases:{"function.dispatch":"built_in"},contains:[].concat(C,P,I,v,[m,{begin:"\\b(deque|list|queue|priority_queue|pair|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array|tuple|optional|variant|function|flat_map|flat_set)\\s*<(?!<)",end:">",keywords:y,contains:["self",l]},{begin:n.IDENT_RE+"::",keywords:y},{match:[/\b(?:enum(?:\s+(?:class|struct))?|class|struct|union)/,/\s+/,/\w+/],className:{1:"keyword",3:"title.class"}}])}}function t(n){const r={type:["boolean","byte","word","String"],built_in:["KeyboardController","MouseController","SoftwareSerial","EthernetServer","EthernetClient","LiquidCrystal","RobotControl","GSMVoiceCall","EthernetUDP","EsploraTFT","HttpClient","RobotMotor","WiFiClient","GSMScanner","FileSystem","Scheduler","GSMServer","YunClient","YunServer","IPAddress","GSMClient","GSMModem","Keyboard","Ethernet","Console","GSMBand","Esplora","Stepper","Process","WiFiUDP","GSM_SMS","Mailbox","USBHost","Firmata","PImage","Client","Server","GSMPIN","FileIO","Bridge","Serial","EEPROM","Stream","Mouse","Audio","Servo","File","Task","GPRS","WiFi","Wire","TFT","GSM","SPI","SD"],_hints:["setup","loop","runShellCommandAsynchronously","analogWriteResolution","retrieveCallingNumber","printFirmwareVersion","analogReadResolution","sendDigitalPortPair","noListenOnLocalhost","readJoystickButton","setFirmwareVersion","readJoystickSwitch","scrollDisplayRight","getVoiceCallStatus","scrollDisplayLeft","writeMicroseconds","delayMicroseconds","beginTransmission","getSignalStrength","runAsynchronously","getAsynchronously","listenOnLocalhost","getCurrentCarrier","readAccelerometer","messageAvailable","sendDigitalPorts","lineFollowConfig","countryNameWrite","runShellCommand","readStringUntil","rewindDirectory","readTemperature","setClockDivider","readLightSensor","endTransmission","analogReference","detachInterrupt","countryNameRead","attachInterrupt","encryptionType","readBytesUntil","robotNameWrite","readMicrophone","robotNameRead","cityNameWrite","userNameWrite","readJoystickY","readJoystickX","mouseReleased","openNextFile","scanNetworks","noInterrupts","digitalWrite","beginSpeaker","mousePressed","isActionDone","mouseDragged","displayLogos","noAutoscroll","addParameter","remoteNumber","getModifiers","keyboardRead","userNameRead","waitContinue","processInput","parseCommand","printVersion","readNetworks","writeMessage","blinkVersion","cityNameRead","readMessage","setDataMode","parsePacket","isListening","setBitOrder","beginPacket","isDirectory","motorsWrite","drawCompass","digitalRead","clearScreen","serialEvent","rightToLeft","setTextSize","leftToRight","requestFrom","keyReleased","compassRead","analogWrite","interrupts","WiFiServer","disconnect","playMelody","parseFloat","autoscroll","getPINUsed","setPINUsed","setTimeout","sendAnalog","readSlider","analogRead","beginWrite","createChar","motorsStop","keyPressed","tempoWrite","readButton","subnetMask","debugPrint","macAddress","writeGreen","randomSeed","attachGPRS","readString","sendString","remotePort","releaseAll","mouseMoved","background","getXChange","getYChange","answerCall","getResult","voiceCall","endPacket","constrain","getSocket","writeJSON","getButton","available","connected","findUntil","readBytes","exitValue","readGreen","writeBlue","startLoop","IPAddress","isPressed","sendSysex","pauseMode","gatewayIP","setCursor","getOemKey","tuneWrite","noDisplay","loadImage","switchPIN","onRequest","onReceive","changePIN","playFile","noBuffer","parseInt","overflow","checkPIN","knobRead","beginTFT","bitClear","updateIR","bitWrite","position","writeRGB","highByte","writeRed","setSpeed","readBlue","noStroke","remoteIP","transfer","shutdown","hangCall","beginSMS","endWrite","attached","maintain","noCursor","checkReg","checkPUK","shiftOut","isValid","shiftIn","pulseIn","connect","println","localIP","pinMode","getIMEI","display","noBlink","process","getBand","running","beginSD","drawBMP","lowByte","setBand","release","bitRead","prepare","pointTo","readRed","setMode","noFill","remove","listen","stroke","detach","attach","noTone","exists","buffer","height","bitSet","circle","config","cursor","random","IRread","setDNS","endSMS","getKey","micros","millis","begin","print","write","ready","flush","width","isPIN","blink","clear","press","mkdir","rmdir","close","point","yield","image","BSSID","click","delay","read","text","move","peek","beep","rect","line","open","seek","fill","size","turn","stop","home","find","step","tone","sqrt","RSSI","SSID","end","bit","tan","cos","sin","pow","map","abs","max","min","get","run","put"],literal:["DIGITAL_MESSAGE","FIRMATA_STRING","ANALOG_MESSAGE","REPORT_DIGITAL","REPORT_ANALOG","INPUT_PULLUP","SET_PIN_MODE","INTERNAL2V56","SYSTEM_RESET","LED_BUILTIN","INTERNAL1V1","SYSEX_START","INTERNAL","EXTERNAL","DEFAULT","OUTPUT","INPUT","HIGH","LOW"]},a=e(n),i=a.keywords;return i.type=[...i.type,...r.type],i.literal=[...i.literal,...r.literal],i.built_in=[...i.built_in,...r.built_in],i._hints=r._hints,a.name="Arduino",a.aliases=["ino"],a.supersetOf="cpp",a}return Wi=t,Wi}var Ki,zd;function hv(){if(zd)return Ki;zd=1;function e(t){const n={variants:[t.COMMENT("^[ \\t]*(?=#)","$",{relevance:0,excludeBegin:!0}),t.COMMENT("[;@]","$",{relevance:0}),t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE]};return{name:"ARM Assembly",case_insensitive:!0,aliases:["arm"],keywords:{$pattern:"\\.?"+t.IDENT_RE,meta:".2byte .4byte .align .ascii .asciz .balign .byte .code .data .else .end .endif .endm .endr .equ .err .exitm .extern .global .hword .if .ifdef .ifndef .include .irp .long .macro .rept .req .section .set .skip .space .text .word .arm .thumb .code16 .code32 .force_thumb .thumb_func .ltorg ALIAS ALIGN ARM AREA ASSERT ATTR CN CODE CODE16 CODE32 COMMON CP DATA DCB DCD DCDU DCDO DCFD DCFDU DCI DCQ DCQU DCW DCWU DN ELIF ELSE END ENDFUNC ENDIF ENDP ENTRY EQU EXPORT EXPORTAS EXTERN FIELD FILL FUNCTION GBLA GBLL GBLS GET GLOBAL IF IMPORT INCBIN INCLUDE INFO KEEP LCLA LCLL LCLS LTORG MACRO MAP MEND MEXIT NOFP OPT PRESERVE8 PROC QN READONLY RELOC REQUIRE REQUIRE8 RLIST FN ROUT SETA SETL SETS SN SPACE SUBT THUMB THUMBX TTL WHILE WEND ",built_in:"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 w0 w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12 w13 w14 w15 w16 w17 w18 w19 w20 w21 w22 w23 w24 w25 w26 w27 w28 w29 w30 x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 pc lr sp ip sl sb fp a1 a2 a3 a4 v1 v2 v3 v4 v5 v6 v7 v8 f0 f1 f2 f3 f4 f5 f6 f7 p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12 q13 q14 q15 cpsr_c cpsr_x cpsr_s cpsr_f cpsr_cx cpsr_cxs cpsr_xs cpsr_xsf cpsr_sf cpsr_cxsf spsr_c spsr_x spsr_s spsr_f spsr_cx spsr_cxs spsr_xs spsr_xsf spsr_sf spsr_cxsf s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 s16 s17 s18 s19 s20 s21 s22 s23 s24 s25 s26 s27 s28 s29 s30 s31 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 d16 d17 d18 d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31 {PC} {VAR} {TRUE} {FALSE} {OPT} {CONFIG} {ENDIAN} {CODESIZE} {CPU} {FPU} {ARCHITECTURE} {PCSTOREOFFSET} {ARMASM_VERSION} {INTER} {ROPI} {RWPI} {SWST} {NOSWST} . @"},contains:[{className:"keyword",begin:"\\b(adc|(qd?|sh?|u[qh]?)?add(8|16)?|usada?8|(q|sh?|u[qh]?)?(as|sa)x|and|adrl?|sbc|rs[bc]|asr|b[lx]?|blx|bxj|cbn?z|tb[bh]|bic|bfc|bfi|[su]bfx|bkpt|cdp2?|clz|clrex|cmp|cmn|cpsi[ed]|cps|setend|dbg|dmb|dsb|eor|isb|it[te]{0,3}|lsl|lsr|ror|rrx|ldm(([id][ab])|f[ds])?|ldr((s|ex)?[bhd])?|movt?|mvn|mra|mar|mul|[us]mull|smul[bwt][bt]|smu[as]d|smmul|smmla|mla|umlaal|smlal?([wbt][bt]|d)|mls|smlsl?[ds]|smc|svc|sev|mia([bt]{2}|ph)?|mrr?c2?|mcrr2?|mrs|msr|orr|orn|pkh(tb|bt)|rbit|rev(16|sh)?|sel|[su]sat(16)?|nop|pop|push|rfe([id][ab])?|stm([id][ab])?|str(ex)?[bhd]?|(qd?)?sub|(sh?|q|u[qh]?)?sub(8|16)|[su]xt(a?h|a?b(16)?)|srs([id][ab])?|swpb?|swi|smi|tst|teq|wfe|wfi|yield)(eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al|hs|lo)?[sptrx]?(?=\\s)"},n,t.QUOTE_STRING_MODE,{className:"string",begin:"'",end:"[^\\\\]'",relevance:0},{className:"title",begin:"\\|",end:"\\|",illegal:"\\n",relevance:0},{className:"number",variants:[{begin:"[#$=]?0x[0-9a-f]+"},{begin:"[#$=]?0b[01]+"},{begin:"[#$=]\\d+"},{begin:"\\b\\d+"}],relevance:0},{className:"symbol",variants:[{begin:"^[ \\t]*[a-z_\\.\\$][a-z0-9_\\.\\$]+:"},{begin:"^[a-z_\\.\\$][a-z0-9_\\.\\$]+"},{begin:"[=#]\\w+"}],relevance:0}]}}return Ki=e,Ki}var Qi,Wd;function vv(){if(Wd)return Qi;Wd=1;function e(t){const n=t.regex,r=n.concat(/[\p{L}_]/u,n.optional(/[\p{L}0-9_.-]*:/u),/[\p{L}0-9_.-]*/u),a=/[\p{L}0-9._:-]+/u,i={className:"symbol",begin:/&[a-z]+;|[0-9]+;|[a-f0-9]+;/},o={begin:/\s/,contains:[{className:"keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}]},s=t.inherit(o,{begin:/\(/,end:/\)/}),c=t.inherit(t.APOS_STRING_MODE,{className:"string"}),l=t.inherit(t.QUOTE_STRING_MODE,{className:"string"}),_={endsWithParent:!0,illegal:/,relevance:0,contains:[{className:"attr",begin:a,relevance:0},{begin:/=\s*/,relevance:0,contains:[{className:"string",endsParent:!0,variants:[{begin:/"/,end:/"/,contains:[i]},{begin:/'/,end:/'/,contains:[i]},{begin:/[^\s"'=<>`]+/}]}]}]};return{name:"HTML, XML",aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],case_insensitive:!0,unicodeRegex:!0,contains:[{className:"meta",begin://,relevance:10,contains:[o,l,c,s,{begin:/\[/,end:/\]/,contains:[{className:"meta",begin://,contains:[o,s,l,c]}]}]},t.COMMENT(//,{relevance:10}),{begin://,relevance:10},i,{className:"meta",end:/\?>/,variants:[{begin:/<\?xml/,relevance:10,contains:[l]},{begin:/<\?[a-z][a-z0-9]+/}]},{className:"tag",begin:/
diff --git a/webclient/src/components/messages/ContentCard.vue b/webclient/src/components/messages/ContentCard.vue
index 241bc33..be2a9f6 100644
--- a/webclient/src/components/messages/ContentCard.vue
+++ b/webclient/src/components/messages/ContentCard.vue
@@ -48,7 +48,7 @@
v-else-if="detectedContentType === 'stl'"
:src="viewerUrl('stl')"
class="content-iframe"
- sandbox="allow-scripts"
+ sandbox="allow-scripts allow-same-origin"
loading="lazy"
/>
diff --git a/webclient/src/composables/useWebSocket.js b/webclient/src/composables/useWebSocket.js
index 5a3f9ff..30ad7a6 100644
--- a/webclient/src/composables/useWebSocket.js
+++ b/webclient/src/composables/useWebSocket.js
@@ -145,6 +145,7 @@
case 'stream_end': chat.onStreamEnd(event); break
case 'stream_stopped': chat.onStreamStopped(); break
case 'profile_switched': chat.onProfileSwitched(event); break
+ case 'compression_started':chat.onCompressionStarted(event); break
case 'context_compressed':chat.onContextCompressed(event); break
case 'error': chat.onError(event); break
case 'replay_start': chat.onReplayStart(); break
diff --git a/webclient/src/stores/chat.js b/webclient/src/stores/chat.js
index 5093abe..5f787a7 100644
--- a/webclient/src/stores/chat.js
+++ b/webclient/src/stores/chat.js
@@ -446,9 +446,23 @@
currentProfileId.value = data.profile_id
}
+ function onCompressionStarted(data) {
+ if (data?.context_tokens != null) contextTokens.value = data.context_tokens
+ if (data?.max_context_tokens != null) maxContextTokens.value = data.max_context_tokens
+ // Insert a transient notice that will be replaced by the real compression card
+ messages.value.push({
+ id: `compress_pending_${Date.now()}`,
+ role: 'system',
+ type: 'compression_pending',
+ text: 'Compressing context…'
+ })
+ }
+
function onContextCompressed(data) {
if (data?.context_tokens != null) contextTokens.value = data.context_tokens
if (data?.max_context_tokens != null) maxContextTokens.value = data.max_context_tokens
+ // Remove any pending compression notices — the real one is here now
+ messages.value = messages.value.filter(m => m.type !== 'compression_pending')
messages.value.push({
id: `compress_${Date.now()}`,
role: 'system',
@@ -685,6 +699,7 @@
onStreamEnd,
onStreamStopped,
onProfileSwitched,
+ onCompressionStarted,
onContextCompressed,
onError,
loadRecall,