diff --git a/README.md b/README.md index c6dc398..c84d5f8 100644 --- a/README.md +++ b/README.md @@ -388,7 +388,7 @@ example.com { ## π Updating yt-dlp -MyTube is powered by [yt-dlp](https://github.com/yt-dlp/yt-dlp), which requires frequent updates as video sites change their layouts. A nightly build automatically publishes a new Docker image whenever a new yt-dlp version is available, so keep your container up to date β [watchtower](https://github.com/nicholas-fedor/watchtower) works well for this. +MyTube is powered by [yt-dlp](https://github.com/yt-dlp/yt-dlp), which requires frequent updates as video sites change their layouts. A new MyTube Docker image is published automatically when a new yt-dlp stable release is available, so keep your container up to date β [watchtower](https://github.com/nicholas-fedor/watchtower) works well for this. To follow yt-dlp's nightly channel instead, set `YTDL_NIGHTLY_UPDATE_TIME`. ## π§ Troubleshooting and submitting issues diff --git a/app/main.py b/app/main.py index 9db6584..8a63492 100644 --- a/app/main.py +++ b/app/main.py @@ -512,6 +512,31 @@ def _forget_public_download(url: str | None = None, *, dl_id: str | None = None, public_visit_downloads.pop(visit_id, None) +def _get_public_history(visit_id: str): + """Return (active_items, done_items) for *visit_id* in the same format + as ``dqueue.get()``: ``([(key, DownloadInfo), ...], [(key, DownloadInfo), ...])``. + Only downloads whose URL is registered to *visit_id* are included. + """ + urls = public_visit_downloads.get(visit_id, set()) + if not urls: + return ([], []) + + active = [] + for key, info in dqueue.queue.saved_items(): + if info.url in urls: + active.append((key, info)) + for key, info in dqueue.pending.saved_items(): + if info.url in urls: + active.append((key, info)) + + done = [] + for key, info in dqueue.done.saved_items(): + if info.url in urls: + done.append((key, info)) + + return (active, done) + + async def _emit_download_event(event: str, payload, *, url: str | None = None, dl_id: str | None = None, dl_key: str | None = None): if not config.PUBLIC_MODE: await sio.emit(event, payload) @@ -563,7 +588,13 @@ class Notifier(DownloadQueueNotifier): async def completed(self, dl): log.info(f"Notifier: Download completed - {dl.title}") await _emit_download_event('completed', serializer.encode(dl), url=dl.url, dl_id=dl.id, dl_key=getattr(dl, 'key', None)) - _forget_public_download(dl.url, dl_id=dl.id, dl_key=getattr(dl, 'key', None)) + # Remove transient id/key ownership β they were only needed for + # routing events to the owning session while the download was active. + # Keep public_download_owner[url] and public_visit_downloads[visit_id] + # intact so reconnecting clients can discover their completed downloads + # via _get_public_history(). + public_download_owner_by_id.pop(dl.id, None) + public_download_owner_by_key.pop(getattr(dl, 'key', None), None) async def canceled(self, id): log.info(f"Notifier: Download canceled - {id}") @@ -573,6 +604,7 @@ class Notifier(DownloadQueueNotifier): async def cleared(self, id): log.info(f"Notifier: Download cleared - {id}") await _emit_download_event('cleared', serializer.encode(id), url=id, dl_id=id) + _forget_public_download(id, dl_id=id, dl_key=id) dqueue = DownloadQueue(config, Notifier()) @@ -1131,14 +1163,20 @@ async def cookie_status(request): @routes.get(config.URL_PREFIX + 'history') async def history(request): - history = { 'done': [], 'queue': [], 'pending': []} - - for _, v in dqueue.queue.saved_items(): - history['queue'].append(v) - for _, v in dqueue.done.saved_items(): - history['done'].append(v) - for _, v in dqueue.pending.saved_items(): - history['pending'].append(v) + if config.PUBLIC_MODE: + visit_id = request.query.get('visit_id', '').strip() + if not visit_id: + return web.Response(text=serializer.encode({'done': [], 'queue': [], 'pending': []})) + active, done = _get_public_history(visit_id) + history = {'done': [v for _, v in done], 'queue': [v for _, v in active], 'pending': []} + else: + history = { 'done': [], 'queue': [], 'pending': []} + for _, v in dqueue.queue.saved_items(): + history['queue'].append(v) + for _, v in dqueue.done.saved_items(): + history['done'].append(v) + for _, v in dqueue.pending.saved_items(): + history['pending'].append(v) log.info("Sending download history") return web.Response(text=serializer.encode(history)) @@ -1146,13 +1184,17 @@ async def history(request): @sio.event async def connect(sid, environ): log.info(f"Client connected: {sid}") + visit_id = '' if config.PUBLIC_MODE: visit_id = _public_visit_from_environ(environ) if visit_id: public_sid_visit[sid] = visit_id public_visit_sids.setdefault(visit_id, set()).add(sid) if config.PUBLIC_MODE: - await sio.emit('all', serializer.encode(([], [])), to=sid) + if visit_id: + await sio.emit('all', serializer.encode(_get_public_history(visit_id)), to=sid) + else: + await sio.emit('all', serializer.encode(([], [])), to=sid) else: await sio.emit('all', serializer.encode(dqueue.get()), to=sid) if not config.PUBLIC_MODE: @@ -1175,15 +1217,13 @@ async def disconnect(sid): if sids: return public_visit_sids.pop(visit_id, None) - owned = list(public_visit_downloads.pop(visit_id, set())) - for url in owned: - public_download_owner.pop(url, None) - # remove any lingering id ownership for this visit - for dl_id, owner in list(public_download_owner_by_id.items()): - if owner == visit_id: - public_download_owner_by_id.pop(dl_id, None) - if owned: - await dqueue.cancel(owned) + # Do NOT cancel downloads β they survive browser refresh. + # Do NOT remove visitβURL mappings β they are needed by + # _get_public_history() when the user reconnects with the + # same visit_id (persisted via browser cookie). + # Transient id/key ownership (public_download_owner_by_id, + # public_download_owner_by_key) is cleaned up by the + # completed / canceled / cleared notifiers. def get_custom_dirs(): diff --git a/app/tests/test_download_queue.py b/app/tests/test_download_queue.py index 3fbec16..de8355f 100644 --- a/app/tests/test_download_queue.py +++ b/app/tests/test_download_queue.py @@ -7,8 +7,9 @@ import tempfile from unittest.mock import AsyncMock, MagicMock, patch import pytest +import time -from ytdl import DownloadQueue +from ytdl import DownloadInfo, DownloadQueue @pytest.fixture @@ -472,3 +473,243 @@ async def test_add_sets_clip_bounds_on_download_info(dq_env): download = dq.pending.get("https://example.com/clip") assert download.info.clip_start == 10.0 assert download.info.clip_end == 99.5 + + +def _upcoming_entry(url: str, *, release_timestamp: float | None = None) -> dict: + return { + "_type": "video", + "id": "live1", + "title": "Upcoming Stream", + "url": url, + "webpage_url": url, + "live_status": "is_upcoming", + "release_timestamp": release_timestamp if release_timestamp is not None else time.time() + 3600, + } + + +@pytest.mark.asyncio +async def test_add_upcoming_stream_scheduled_without_starting(dq_env): + notifier = AsyncMock() + url = "https://example.com/live-upcoming" + start_mock = AsyncMock() + + dq = DownloadQueue(dq_env, notifier) + with patch.object(DownloadQueue, "_DownloadQueue__start_download", start_mock): + result = await dq.add_entry( + _upcoming_entry(url), + "video", + "auto", + "any", + "best", + "", + "", + 0, + auto_start=True, + ) + + assert result["status"] == "ok" + assert dq.queue.exists(url) + download = dq.queue.get(url) + assert download.info.status == "scheduled" + assert download.info.live_status == "is_upcoming" + assert download.info.live_release_timestamp is not None + start_mock.assert_not_called() + assert url in dq._scheduled_probe_at + + +@pytest.mark.asyncio +async def test_probe_scheduled_starts_when_live(dq_env): + notifier = AsyncMock() + url = "https://example.com/live-upcoming" + start_mock = AsyncMock() + + dq = DownloadQueue(dq_env, notifier) + with patch.object(DownloadQueue, "_DownloadQueue__start_download", start_mock): + await dq.add_entry( + _upcoming_entry(url), + "video", + "auto", + "any", + "best", + "", + "", + 0, + auto_start=True, + ) + + download = dq.queue.get(url) + + def fake_probe_extract(self, probe_url, ytdl_options_presets=None, ytdl_options_overrides=None): + assert probe_url == url + return { + "_type": "video", + "id": "live1", + "title": "Live Now", + "url": url, + "webpage_url": url, + "live_status": "is_live", + "formats": [{"format_id": "22"}], + } + + with patch.object(DownloadQueue, "_DownloadQueue__extract_info", fake_probe_extract), \ + patch.object(DownloadQueue, "_DownloadQueue__start_download", start_mock): + await dq._probe_scheduled_download(download) + + assert url not in dq._scheduled_probe_at + assert download.info.live_status == "is_live" + assert download.info.status == "pending" + start_mock.assert_called_once_with(download) + + +@pytest.mark.asyncio +async def test_import_scheduled_re_registers_monitor(dq_env): + notifier = AsyncMock() + url = "https://example.com/live-restart" + release = time.time() + 7200 + + info = DownloadInfo( + id="live1", + title="Upcoming Stream", + url=url, + quality="best", + download_type="video", + codec="auto", + format="any", + folder="", + custom_name_prefix="", + error=None, + entry=None, + playlist_item_limit=0, + split_by_chapters=False, + chapter_template="", + live_status="is_upcoming", + live_release_timestamp=release, + ) + info.status = "scheduled" + + dq = DownloadQueue(dq_env, notifier) + start_mock = AsyncMock() + with patch.object(DownloadQueue, "_DownloadQueue__start_download", start_mock): + await dq._DownloadQueue__add_download(info, True) + + assert dq.queue.exists(url) + assert dq.queue.get(url).info.status == "scheduled" + assert url in dq._scheduled_probe_at + start_mock.assert_not_called() + + +@pytest.mark.asyncio +async def test_probe_transient_error_retries_without_failing(dq_env): + """A single probe failure must not abandon the scheduled stream.""" + import ytdl + + notifier = AsyncMock() + url = "https://example.com/live-transient" + start_mock = AsyncMock() + + dq = DownloadQueue(dq_env, notifier) + with patch.object(DownloadQueue, "_DownloadQueue__start_download", start_mock): + await dq.add_entry( + _upcoming_entry(url), + "video", "auto", "any", "best", "", "", 0, + auto_start=True, + ) + download = dq.queue.get(url) + + def boom(self, *args, **kwargs): + raise ytdl.yt_dlp.utils.YoutubeDLError("temporary network glitch") + + before = time.time() + with patch.object(DownloadQueue, "_DownloadQueue__extract_info", boom): + await dq._probe_scheduled_download(download) + + # Still scheduled, still monitored, probe rescheduled into the future. + assert download.info.status == "scheduled" + assert url in dq._scheduled_probe_at + assert dq._scheduled_probe_at[url] >= before + assert dq._scheduled_probe_failures[url] == 1 + notifier.completed.assert_not_called() + + +@pytest.mark.asyncio +async def test_probe_gives_up_after_max_failures(dq_env): + import ytdl + + notifier = AsyncMock() + url = "https://example.com/live-dead" + start_mock = AsyncMock() + + dq = DownloadQueue(dq_env, notifier) + with patch.object(DownloadQueue, "_DownloadQueue__start_download", start_mock): + await dq.add_entry( + _upcoming_entry(url), + "video", "auto", "any", "best", "", "", 0, + auto_start=True, + ) + download = dq.queue.get(url) + + def boom(self, *args, **kwargs): + raise ytdl.yt_dlp.utils.YoutubeDLError("stream was deleted") + + with patch.object(DownloadQueue, "_DownloadQueue__extract_info", boom): + for _ in range(ytdl._LIVE_PROBE_MAX_FAILURES): + await dq._probe_scheduled_download(download) + + assert url not in dq._scheduled_probe_at + assert not dq.queue.exists(url) + assert dq.done.exists(url) + assert download.info.status == "error" + notifier.completed.assert_awaited() + + +@pytest.mark.asyncio +async def test_probe_recovers_after_transient_then_starts(dq_env): + """A transient failure followed by a successful live probe should start the download.""" + import ytdl + + notifier = AsyncMock() + url = "https://example.com/live-recover" + start_mock = AsyncMock() + + dq = DownloadQueue(dq_env, notifier) + with patch.object(DownloadQueue, "_DownloadQueue__start_download", start_mock): + await dq.add_entry( + _upcoming_entry(url), + "video", "auto", "any", "best", "", "", 0, + auto_start=True, + ) + download = dq.queue.get(url) + # The scheduling placeholder error is set on add. + assert download.info.error + + def boom(self, *args, **kwargs): + raise ytdl.yt_dlp.utils.YoutubeDLError("temporary glitch") + + with patch.object(DownloadQueue, "_DownloadQueue__extract_info", boom): + await dq._probe_scheduled_download(download) + assert dq._scheduled_probe_failures[url] == 1 + + def live_now(self, *args, **kwargs): + return { + "_type": "video", "id": "live1", "title": "Live Now", + "url": url, "webpage_url": url, "live_status": "is_live", + "formats": [{"format_id": "22"}], + } + + with patch.object(DownloadQueue, "_DownloadQueue__extract_info", live_now), \ + patch.object(DownloadQueue, "_DownloadQueue__start_download", start_mock): + await dq._probe_scheduled_download(download) + + assert url not in dq._scheduled_probe_at + assert url not in dq._scheduled_probe_failures + assert download.info.status == "pending" + # Placeholder error/msg cleared now that a real download is starting. + assert download.info.error is None + assert download.info.msg is None + start_mock.assert_called_once_with(download) + + +def test_seconds_until_next_probe_none_when_empty(dq_env): + notifier = AsyncMock() + dq = DownloadQueue(dq_env, notifier) + assert dq._seconds_until_next_probe() is None diff --git a/app/ytdl.py b/app/ytdl.py index fa18494..f4d7378 100644 --- a/app/ytdl.py +++ b/app/ytdl.py @@ -4,7 +4,9 @@ import yt_dlp import collections import collections.abc import copy +import io import pickle +import sys from collections import OrderedDict import time import asyncio @@ -24,6 +26,81 @@ from subscriptions import _entry_id log = logging.getLogger('ytdl') +_LIVE_CHECK_INTERVAL = 60 +_LIVE_MAX_CHECK_INTERVAL = 3600 +# Consecutive probe failures (network blips, rate limits, transient extractor +# errors) tolerated before a scheduled live download is abandoned as errored. +_LIVE_PROBE_MAX_FAILURES = 5 + + +def _build_user_error_message(stderr_output: str, error_msg: str) -> str: + """Build a user-friendly error message from captured yt-dlp stderr output + and the exception/error string. + + Maps common yt-dlp WARNING/ERROR patterns to actionable messages so users + can understand and fix the problem without reading raw server logs. + """ + stderr_lower = stderr_output.lower() + + # Bot detection / cookies required + if 'sign in to confirm' in stderr_lower or 'not a bot' in stderr_lower: + return ( + 'YouTube requires sign-in for this video. ' + 'Please export your YouTube cookies from your browser ' + 'and upload them via the Upload Cookies button.' + ) + + # Geo-restricted + if 'video unavailable' in stderr_lower: + if 'geo' in stderr_lower or 'country' in stderr_lower: + return f'This video is not available in your region. ({error_msg})' + if 'private' in stderr_lower: + return f'This video is private. ({error_msg})' + return f'Video unavailable β it may be deleted, private, or region-locked. ({error_msg})' + + # HTTP errors + if 'http error 403' in stderr_lower: + return f'Access denied (HTTP 403). The server is blocking the request. ({error_msg})' + if 'http error 404' in stderr_lower: + return f'Video not found (HTTP 404). The URL may be incorrect or the content was removed. ({error_msg})' + if 'http error 429' in stderr_lower: + return f'Too many requests (HTTP 429). The server is rate-limiting. Try again later. ({error_msg})' + + # Age restriction + if 'age' in stderr_lower and ('restrict' in stderr_lower or 'limit' in stderr_lower): + return ( + 'This is an age-restricted video. ' + 'Upload YouTube cookies with age verification to download it. ' + f'({error_msg})' + ) + + # Network issues + if any(term in stderr_lower for term in ('network', 'connection', 'timeout', 'timed out')): + return f'Network error β please check your internet connection. ({error_msg})' + + # No formats / format not available β could be cookies or actual format issue + if 'no video formats' in stderr_lower or 'requested format' in stderr_lower: + return ( + f'{error_msg}\n' + 'Possible causes: (1) YouTube bot detection β try uploading cookies, ' + '(2) The selected format/quality is not available for this video.' + ) + + # Login required (generic) + if 'login' in stderr_lower and 'required' in stderr_lower: + return ( + 'This video requires login. ' + 'Please export and upload your YouTube cookies. ' + f'({error_msg})' + ) + + # DRM / copyright + if 'drm' in stderr_lower or 'copyright' in stderr_lower: + return f'This video is DRM-protected or copyright-restricted and cannot be downloaded. ({error_msg})' + + # Include the original error β better than showing nothing + return error_msg if error_msg else 'Download failed (unknown error)' + # Characters that are invalid in Windows/NTFS path components. These are pre- # sanitised when substituting playlist/channel titles into output templates so @@ -194,6 +271,8 @@ class DownloadInfo: ytdl_options_overrides=None, clip_start=None, clip_end=None, + live_status=None, + live_release_timestamp=None, ): self.id = id if len(custom_name_prefix) == 0 else f'{custom_name_prefix}.{id}' self.title = title if len(custom_name_prefix) == 0 else f'{custom_name_prefix}.{title}' @@ -223,6 +302,8 @@ class DownloadInfo: self.clip_start = clip_start self.clip_end = clip_end self.chapter_files = [] + self.live_status = live_status + self.live_release_timestamp = live_release_timestamp self.subtitle_files = [] def __setstate__(self, state): @@ -299,6 +380,10 @@ class DownloadInfo: self.clip_end = None if not hasattr(self, "download_phase"): self.download_phase = None + if not hasattr(self, "live_status"): + self.live_status = None + if not hasattr(self, "live_release_timestamp"): + self.live_release_timestamp = None _PERSISTED_DOWNLOAD_FIELDS = ( @@ -320,6 +405,8 @@ _PERSISTED_DOWNLOAD_FIELDS = ( "ytdl_options_overrides", "clip_start", "clip_end", + "live_status", + "live_release_timestamp", "status", "download_phase", "timestamp", @@ -527,6 +614,7 @@ class Download: def _download(self): log.info(f"Starting download for: {self.info.title} ({self.info.url})") + stderr_buf = None try: debug_logging = logging.getLogger().isEnabledFor(logging.DEBUG) def put_status(st): @@ -634,12 +722,34 @@ class Download: [(start, end)], ) - ret = yt_dlp.YoutubeDL(params=ytdl_params).download([self.info.url]) - self.status_queue.put({'status': 'finished' if ret == 0 else 'error', 'download_phase': None}) + # Capture stderr to collect yt-dlp WARNING messages + # (e.g. "Sign in to confirm you're not a bot"). + stderr_buf = io.StringIO() + old_stderr = sys.stderr + sys.stderr = stderr_buf + try: + ret = yt_dlp.YoutubeDL(params=ytdl_params).download([self.info.url]) + finally: + sys.stderr = old_stderr + + stderr_output = stderr_buf.getvalue() + + if ret == 0: + self.status_queue.put({'status': 'finished', 'download_phase': None}) + else: + msg = _build_user_error_message(stderr_output, 'Download failed') + self.status_queue.put({'status': 'error', 'msg': msg, 'download_phase': None}) log.info(f"Finished download for: {self.info.title}") except yt_dlp.utils.YoutubeDLError as exc: - log.error(f"Download error for {self.info.title}: {str(exc)}") - self.status_queue.put({'status': 'error', 'msg': str(exc), 'download_phase': None}) + stderr_output = stderr_buf.getvalue() if stderr_buf is not None else '' + msg = _build_user_error_message(stderr_output, str(exc)) + log.error(f"Download error for {self.info.title}: {msg}") + self.status_queue.put({'status': 'error', 'msg': msg, 'download_phase': None}) + except Exception as exc: + stderr_output = stderr_buf.getvalue() if stderr_buf is not None else '' + msg = _build_user_error_message(stderr_output, str(exc)) + log.error(f"Unexpected download error for {self.info.title}: {msg}") + self.status_queue.put({'status': 'error', 'msg': msg, 'download_phase': None}) async def start(self, notifier): log.info(f"Preparing download for: {self.info.title}") @@ -951,6 +1061,10 @@ class DownloadQueue: self.done.load() self._add_generation = 0 self._canceled_urls = set() # URLs canceled during current playlist add + self._scheduled_probe_at: dict[str, float] = {} + self._scheduled_probe_failures: dict[str, int] = {} + self._live_monitor_task: Optional[asyncio.Task] = None + self._live_monitor_wakeup = asyncio.Event() @staticmethod def _download_key(dl: DownloadInfo) -> str: @@ -985,15 +1099,171 @@ class DownloadQueue: async def initialize(self): log.info("Initializing DownloadQueue") + self._start_live_monitor() asyncio.create_task(self.__import_queue()) asyncio.create_task(self.__import_pending()) - async def __start_download(self, download, generation): - if generation != download.start_generation or download.canceled or download.paused: - log.info(f"Download {download.info.title} was canceled or paused, skipping start.") + def _start_live_monitor(self) -> None: + if self._live_monitor_task is not None and not self._live_monitor_task.done(): + return + self._live_monitor_task = asyncio.create_task(self._live_monitor_loop()) + self._live_monitor_task.add_done_callback( + lambda t: log.error("Live monitor loop failed: %s", t.exception()) + if not t.cancelled() and t.exception() + else None + ) + + def _register_scheduled(self, download: Download) -> None: + self._scheduled_probe_at[download.info.url] = 0 + self._scheduled_probe_failures.pop(download.info.url, None) + self._start_live_monitor() + self._wake_live_monitor() + + def _unregister_scheduled(self, url: str) -> None: + self._scheduled_probe_at.pop(url, None) + self._scheduled_probe_failures.pop(url, None) + + def _wake_live_monitor(self) -> None: + try: + self._live_monitor_wakeup.set() + except RuntimeError: + pass + + def _probe_interval_seconds(self, release_timestamp: Any) -> float: + if release_timestamp is not None: + try: + diff = float(release_timestamp) - time.time() + if diff > 0: + return max(_LIVE_CHECK_INTERVAL, min(diff, _LIVE_MAX_CHECK_INTERVAL)) + except (TypeError, ValueError): + pass + return float(_LIVE_CHECK_INTERVAL) + + def _seconds_until_next_probe(self) -> Optional[float]: + """Time until the earliest scheduled probe, or None when nothing is scheduled.""" + if not self._scheduled_probe_at: + return None + return max(0.0, min(self._scheduled_probe_at.values()) - time.time()) + + async def _live_monitor_loop(self) -> None: + while True: + timeout = self._seconds_until_next_probe() + try: + await asyncio.wait_for(self._live_monitor_wakeup.wait(), timeout=timeout) + except asyncio.TimeoutError: + pass + self._live_monitor_wakeup.clear() + now = time.time() + due: list[Download] = [] + for url, probe_at in list(self._scheduled_probe_at.items()): + if now < probe_at: + continue + if not self.queue.exists(url): + self._unregister_scheduled(url) + continue + download = self.queue.get(url) + if download.info.status != 'scheduled' or download.canceled: + self._unregister_scheduled(url) + continue + due.append(download) + for download in due: + try: + await self._probe_scheduled_download(download) + except Exception as exc: + # Defensive: _probe_scheduled_download handles its own errors, + # but never let an unexpected failure leave probe_at in the past + # (which would spin this loop) or kill the monitor task. + log.exception("Scheduled live probe crashed for %s: %s", download.info.url, exc) + if download.info.url in self._scheduled_probe_at: + self._scheduled_probe_at[download.info.url] = time.time() + _LIVE_CHECK_INTERVAL + + async def _probe_scheduled_download(self, download: Download) -> None: + url = download.info.url + info = download.info + if info.status != 'scheduled' or download.canceled: + self._unregister_scheduled(url) + return + + try: + entry = await asyncio.get_running_loop().run_in_executor( + None, + partial( + self.__extract_info, + url, + getattr(info, 'ytdl_options_presets', None), + getattr(info, 'ytdl_options_overrides', {}) or {}, + ), + ) + except Exception as exc: + # Treat all probe failures (transient network blips, rate limits, + # extractor errors) as recoverable up to a point: retry on the next + # interval and only give up after repeated consecutive failures so a + # momentary glitch doesn't abandon a stream the user is waiting for. + fails = self._scheduled_probe_failures.get(url, 0) + 1 + self._scheduled_probe_failures[url] = fails + if fails >= _LIVE_PROBE_MAX_FAILURES: + log.warning( + "Giving up on scheduled live probe for %s after %d consecutive failures: %s", + info.title, fails, exc, + ) + info.status = 'error' + info.msg = str(exc) + if not info.error: + info.error = str(exc) + self._unregister_scheduled(url) + self.queue.delete(url) + self.done.put(download) + await self.notifier.completed(info) + else: + log.warning( + "Scheduled live probe failed for %s (attempt %d/%d), will retry: %s", + info.title, fails, _LIVE_PROBE_MAX_FAILURES, exc, + ) + self._scheduled_probe_at[url] = time.time() + _LIVE_CHECK_INTERVAL + return + + # Successful probe resets the transient-failure streak. + self._scheduled_probe_failures.pop(url, None) + + release_ts = entry.get('release_timestamp') + live_status = entry.get('live_status') + if release_ts is not None: + info.live_release_timestamp = release_ts + if live_status is not None: + info.live_status = live_status + + if live_status == 'is_upcoming': + self._scheduled_probe_at[url] = time.time() + self._probe_interval_seconds(release_ts) + await self.notifier.updated(info) + return + + self._unregister_scheduled(url) + info.status = 'pending' + # Clear the "scheduled to start at ..." placeholder now that the stream + # is live and a real download is about to begin. + info.error = None + info.msg = None + await self.notifier.updated(info) + asyncio.create_task(self.__start_download(download)) + + def _schedule_upcoming_download(self, download: Download) -> None: + download.info.status = 'scheduled' + self.queue.put(download) + self._register_scheduled(download) + + def _force_start_scheduled(self, download: Download) -> None: + self._unregister_scheduled(download.info.url) + download.info.status = 'pending' + download.info.error = None + download.info.msg = None + asyncio.create_task(self.__start_download(download)) + + async def __start_download(self, download): + if download.canceled: + log.info(f"Download {download.info.title} was canceled, skipping start.") return async with self.semaphore: - if generation != download.start_generation or download.canceled or download.paused: + if download.canceled or download.paused: log.info(f"Download {download.info.title} was canceled or paused, skipping start.") return await download.start(self.notifier) @@ -1159,10 +1429,16 @@ class DownloadQueue: log.info(f'playlist limit is set. Processing only first {playlist_item_limit} entries') ytdl_options['playlistend'] = playlist_item_limit download = Download(dldirectory, self.config.TEMP_DIR, output, output_chapter, dl.quality, dl.format, ytdl_options, dl) + is_upcoming = ( + getattr(dl, 'live_status', None) == 'is_upcoming' + or getattr(dl, 'status', None) == 'scheduled' + ) if auto_start is True: - self.queue.put(download) - download.start_generation += 1 - asyncio.create_task(self.__start_download(download, download.start_generation)) + if is_upcoming: + self._schedule_upcoming_download(download) + else: + self.queue.put(download) + asyncio.create_task(self.__start_download(download)) else: self.pending.put(download) await self.notifier.added(dl) @@ -1288,30 +1564,31 @@ class DownloadQueue: if key in self._canceled_urls: log.info(f'Skipping canceled URL: {entry.get("title") or key}') return {'status': 'ok'} - dl = DownloadInfo( - id=entry['id'], - title=entry.get('title') or entry['id'], - url=key, - quality=quality, - download_type=download_type, - codec=codec, - format=format, - folder=folder, - custom_name_prefix=custom_name_prefix, - error=error, - entry=entry, - playlist_item_limit=playlist_item_limit, - split_by_chapters=split_by_chapters, - chapter_template=chapter_template, - subtitle_language=subtitle_language, - subtitle_mode=subtitle_mode, - ytdl_options_presets=ytdl_options_presets, - ytdl_options_overrides=ytdl_options_overrides, - clip_start=clip_start, - clip_end=clip_end, - ) - dl.key = self._download_key(dl) - if not self.queue.exists(dl.key): + if not self.queue.exists(key): + dl = DownloadInfo( + id=entry['id'], + title=entry.get('title') or entry['id'], + url=key, + quality=quality, + download_type=download_type, + codec=codec, + format=format, + folder=folder, + custom_name_prefix=custom_name_prefix, + error=error, + entry=entry, + playlist_item_limit=playlist_item_limit, + split_by_chapters=split_by_chapters, + chapter_template=chapter_template, + subtitle_language=subtitle_language, + subtitle_mode=subtitle_mode, + ytdl_options_presets=ytdl_options_presets, + ytdl_options_overrides=ytdl_options_overrides, + clip_start=clip_start, + clip_end=clip_end, + live_status=entry.get('live_status'), + live_release_timestamp=entry.get('release_timestamp'), + ) await self.__add_download(dl, auto_start) return {'status': 'ok'} return {'status': 'error', 'msg': f'Unsupported resource "{etype}"'} @@ -1431,6 +1708,15 @@ class DownloadQueue: async def start_pending(self, ids): for id in ids: + if self.pending.exists(id): + dl = self.pending.get(id) + self.pending.delete(id) + if getattr(dl.info, 'live_status', None) == 'is_upcoming': + self._schedule_upcoming_download(dl) + else: + self.queue.put(dl) + asyncio.create_task(self.__start_download(dl)) + continue if self.queue.exists(id): dl = self.queue.get(id) if getattr(dl.info, 'status', None) == 'paused' or dl.paused: @@ -1439,17 +1725,12 @@ class DownloadQueue: dl.info.speed = None dl.info.eta = None self.queue.put(dl) - dl.start_generation += 1 - asyncio.create_task(self.__start_download(dl, dl.start_generation)) + asyncio.create_task(self.__start_download(dl)) + continue + if dl.info.status == 'scheduled': + self._force_start_scheduled(dl) continue - if not self.pending.exists(id): - log.warning(f'requested start for non-existent download {id}') - continue - dl = self.pending.get(id) - self.queue.put(dl) - self.pending.delete(id) - dl.start_generation += 1 - asyncio.create_task(self.__start_download(dl, dl.start_generation)) + log.warning(f'requested start for non-existent download {id}') return {'status': 'ok'} async def cancel(self, ids): @@ -1464,11 +1745,14 @@ class DownloadQueue: log.warning(f'requested cancel for non-existent download {id}') continue dl = self.queue.get(id) + dl = self.queue.get(id) if getattr(dl.info, 'status', None) == 'paused' or dl.paused: dl.cancel() self.queue.delete(id) await self.notifier.canceled(id) continue + if dl.info.status == 'scheduled': + self._unregister_scheduled(id) if dl.started(): dl.cancel() else: diff --git a/ui/package.json b/ui/package.json index e7bcc96..d143367 100644 --- a/ui/package.json +++ b/ui/package.json @@ -23,14 +23,14 @@ }, "private": true, "dependencies": { - "@angular/animations": "^21.2.14", - "@angular/common": "^21.2.14", - "@angular/compiler": "^21.2.14", - "@angular/core": "^21.2.14", - "@angular/forms": "^21.2.14", - "@angular/platform-browser": "^21.2.14", - "@angular/platform-browser-dynamic": "^21.2.14", - "@angular/service-worker": "^21.2.14", + "@angular/animations": "^21.2.17", + "@angular/common": "^21.2.17", + "@angular/compiler": "^21.2.17", + "@angular/core": "^21.2.17", + "@angular/forms": "^21.2.17", + "@angular/platform-browser": "^21.2.17", + "@angular/platform-browser-dynamic": "^21.2.17", + "@angular/service-worker": "^21.2.17", "@fortawesome/angular-fontawesome": "~4.0.0", "@fortawesome/fontawesome-svg-core": "^7.2.0", "@fortawesome/free-brands-svg-icons": "^7.2.0", @@ -48,16 +48,16 @@ }, "devDependencies": { "@angular-eslint/builder": "21.1.0", - "@angular/build": "^21.2.13", - "@angular/cli": "^21.2.13", - "@angular/compiler-cli": "^21.2.14", - "@angular/localize": "^21.2.14", + "@angular/build": "^21.2.14", + "@angular/cli": "^21.2.14", + "@angular/compiler-cli": "^21.2.17", + "@angular/localize": "^21.2.17", "@eslint/js": "^9.39.4", "angular-eslint": "21.1.0", "eslint": "^9.39.4", "jsdom": "^27.4.0", "typescript": "~5.9.3", "typescript-eslint": "8.47.0", - "vitest": "^4.1.7" + "vitest": "^4.1.8" } } diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml index 1202bd9..c787cbd 100644 --- a/ui/pnpm-lock.yaml +++ b/ui/pnpm-lock.yaml @@ -9,32 +9,32 @@ importers: .: dependencies: '@angular/animations': - specifier: ^21.2.14 - version: 21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)) + specifier: ^21.2.17 + version: 21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)) '@angular/common': - specifier: ^21.2.14 - version: 21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) + specifier: ^21.2.17 + version: 21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) '@angular/compiler': - specifier: ^21.2.14 - version: 21.2.14 + specifier: ^21.2.17 + version: 21.2.17 '@angular/core': - specifier: ^21.2.14 - version: 21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0) + specifier: ^21.2.17 + version: 21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0) '@angular/forms': - specifier: ^21.2.14 - version: 21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@21.2.14(@angular/animations@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2) + specifier: ^21.2.17 + version: 21.2.17(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@21.2.17(@angular/animations@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2) '@angular/platform-browser': - specifier: ^21.2.14 - version: 21.2.14(@angular/animations@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)) + specifier: ^21.2.17 + version: 21.2.17(@angular/animations@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)) '@angular/platform-browser-dynamic': - specifier: ^21.2.14 - version: 21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/compiler@21.2.14)(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@21.2.14(@angular/animations@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))) + specifier: ^21.2.17 + version: 21.2.17(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/compiler@21.2.17)(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@21.2.17(@angular/animations@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))) '@angular/service-worker': - specifier: ^21.2.14 - version: 21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) + specifier: ^21.2.17 + version: 21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) '@fortawesome/angular-fontawesome': specifier: ~4.0.0 - version: 4.0.0(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)) + version: 4.0.0(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)) '@fortawesome/fontawesome-svg-core': specifier: ^7.2.0 version: 7.2.0 @@ -49,10 +49,10 @@ importers: version: 7.2.0 '@ng-bootstrap/ng-bootstrap': specifier: ^20.0.0 - version: 20.0.0(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/forms@21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@21.2.14(@angular/animations@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2))(@angular/localize@21.2.14(@angular/compiler-cli@21.2.14(@angular/compiler@21.2.14)(typescript@5.9.3))(@angular/compiler@21.2.14))(@popperjs/core@2.11.8)(rxjs@7.8.2) + version: 20.0.0(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/forms@21.2.17(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@21.2.17(@angular/animations@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2))(@angular/localize@21.2.17(@angular/compiler-cli@21.2.17(@angular/compiler@21.2.17)(typescript@5.9.3))(@angular/compiler@21.2.17))(@popperjs/core@2.11.8)(rxjs@7.8.2) '@ng-select/ng-select': specifier: ^21.8.2 - version: 21.8.2(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/forms@21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@21.2.14(@angular/animations@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2)) + version: 21.8.2(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/forms@21.2.17(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@21.2.17(@angular/animations@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2)) '@popperjs/core': specifier: ^2.11.8 version: 2.11.8 @@ -61,10 +61,10 @@ importers: version: 5.3.8(@popperjs/core@2.11.8) ngx-cookie-service: specifier: ^21.3.1 - version: 21.3.1(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)) + version: 21.3.1(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)) ngx-socket-io: specifier: ~4.10.0 - version: 4.10.0(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) + version: 4.10.0(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) rxjs: specifier: ~7.8.2 version: 7.8.2 @@ -77,25 +77,25 @@ importers: devDependencies: '@angular-eslint/builder': specifier: 21.1.0 - version: 21.1.0(@angular/cli@21.2.13(@types/node@25.9.1)(chokidar@5.0.0))(chokidar@5.0.0)(eslint@9.39.4)(typescript@5.9.3) + version: 21.1.0(@angular/cli@21.2.14(@types/node@25.9.3)(chokidar@5.0.0))(chokidar@5.0.0)(eslint@9.39.4)(typescript@5.9.3) '@angular/build': - specifier: ^21.2.13 - version: 21.2.13(@angular/compiler-cli@21.2.14(@angular/compiler@21.2.14)(typescript@5.9.3))(@angular/compiler@21.2.14)(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/localize@21.2.14(@angular/compiler-cli@21.2.14(@angular/compiler@21.2.14)(typescript@5.9.3))(@angular/compiler@21.2.14))(@angular/platform-browser@21.2.14(@angular/animations@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/service-worker@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@25.9.1)(chokidar@5.0.0)(postcss@8.5.15)(tslib@2.8.1)(typescript@5.9.3)(vitest@4.1.7(@types/node@25.9.1)(jsdom@27.4.0)(vite@7.3.2(@types/node@25.9.1)(sass@1.97.3))) + specifier: ^21.2.14 + version: 21.2.14(@angular/compiler-cli@21.2.17(@angular/compiler@21.2.17)(typescript@5.9.3))(@angular/compiler@21.2.17)(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/localize@21.2.17(@angular/compiler-cli@21.2.17(@angular/compiler@21.2.17)(typescript@5.9.3))(@angular/compiler@21.2.17))(@angular/platform-browser@21.2.17(@angular/animations@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/service-worker@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@25.9.3)(chokidar@5.0.0)(postcss@8.5.15)(tslib@2.8.1)(typescript@5.9.3)(vitest@4.1.8(@types/node@25.9.3)(jsdom@27.4.0)(vite@7.3.2(@types/node@25.9.3)(sass@1.97.3))) '@angular/cli': - specifier: ^21.2.13 - version: 21.2.13(@types/node@25.9.1)(chokidar@5.0.0) + specifier: ^21.2.14 + version: 21.2.14(@types/node@25.9.3)(chokidar@5.0.0) '@angular/compiler-cli': - specifier: ^21.2.14 - version: 21.2.14(@angular/compiler@21.2.14)(typescript@5.9.3) + specifier: ^21.2.17 + version: 21.2.17(@angular/compiler@21.2.17)(typescript@5.9.3) '@angular/localize': - specifier: ^21.2.14 - version: 21.2.14(@angular/compiler-cli@21.2.14(@angular/compiler@21.2.14)(typescript@5.9.3))(@angular/compiler@21.2.14) + specifier: ^21.2.17 + version: 21.2.17(@angular/compiler-cli@21.2.17(@angular/compiler@21.2.17)(typescript@5.9.3))(@angular/compiler@21.2.17) '@eslint/js': specifier: ^9.39.4 version: 9.39.4 angular-eslint: specifier: 21.1.0 - version: 21.1.0(@angular/cli@21.2.13(@types/node@25.9.1)(chokidar@5.0.0))(chokidar@5.0.0)(eslint@9.39.4)(typescript-eslint@8.47.0(eslint@9.39.4)(typescript@5.9.3))(typescript@5.9.3) + version: 21.1.0(@angular/cli@21.2.14(@types/node@25.9.3)(chokidar@5.0.0))(chokidar@5.0.0)(eslint@9.39.4)(typescript-eslint@8.47.0(eslint@9.39.4)(typescript@5.9.3))(typescript@5.9.3) eslint: specifier: ^9.39.4 version: 9.39.4 @@ -109,8 +109,8 @@ importers: specifier: 8.47.0 version: 8.47.0(eslint@9.39.4)(typescript@5.9.3) vitest: - specifier: ^4.1.7 - version: 4.1.7(@types/node@25.9.1)(jsdom@27.4.0)(vite@7.3.2(@types/node@25.9.1)(sass@1.97.3)) + specifier: ^4.1.8 + version: 4.1.8(@types/node@25.9.3)(jsdom@27.4.0)(vite@7.3.2(@types/node@25.9.3)(sass@1.97.3)) packages: @@ -177,13 +177,13 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@angular-devkit/architect@0.2102.13': - resolution: {integrity: sha512-fheyi0gPx6b7tT+WQ+ePlzdGqKjPLUK72wg5Z9pkVtQ5+VN/8yB9mlRlmoivngd2FeNG9wMeNynWZGYycnOWVw==} + '@angular-devkit/architect@0.2102.14': + resolution: {integrity: sha512-0+vjVsCkMyJdVjz5XkPW+Bdf/9TI8V2voomx/+o0o+oOaqqiEhptQWFnaIlLr7HasjB0LxXK5P9L0oQ61vxj8Q==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} hasBin: true - '@angular-devkit/core@21.2.13': - resolution: {integrity: sha512-9jLaHcUr6BumIY9nCsBib1q62p259nf++gd2igYJ7mLm1w/0wEacsZ1cC8wCGEe6vx8a+DrD+EVCQ6zivePG2A==} + '@angular-devkit/core@21.2.14': + resolution: {integrity: sha512-RSOWXB9bFc2nwRWMxbIT0RbSNFUrwfBo4N5MNxbyQ69Ndc0gVm3h+3ArHv0qotH4d+pJYbm5ttXu8YqR2kc0CA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} peerDependencies: chokidar: ^5.0.0 @@ -191,8 +191,8 @@ packages: chokidar: optional: true - '@angular-devkit/schematics@21.2.13': - resolution: {integrity: sha512-gifpOcMNiAy49lQmQKhzpxoSfS3qJQSEdJSF5m7RVFkAcmllfcCD76GPN4dhho3wdAnbZ3qr54LtDqrGY4xNjw==} + '@angular-devkit/schematics@21.2.14': + resolution: {integrity: sha512-KMJlQSBEzI4+Cy1Zh72gmGQNN2I1vY+nj9CoRcZPBIi1si+0ZAc49XT85eYl+eQumNTVQviUG7LQqgLDAHml+g==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} '@angular-eslint/builder@21.1.0': @@ -239,14 +239,15 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '*' - '@angular/animations@21.2.14': - resolution: {integrity: sha512-9WLnsJE0xqtd1rVtHMvsAUxFy3OdPks4bdmUIqyw23X/je7ytUALAGWNadffcZBwRpa1A6TUnLr9X4+Draz3kw==} + '@angular/animations@21.2.17': + resolution: {integrity: sha512-zOW8FFa9qfbVkZ5TulxDkl1C3+gEjWfAAD5Z2MycA6pjVJQlLYPiTAGq+flOQ3yZfTT0z6kd5rejQMXWI81Dvg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + deprecated: '@angular/animations is deprecated. Use `animate.enter` and `animate.leave` instead. For more information see: https://v22.angular.dev/guide/animations.' peerDependencies: - '@angular/core': 21.2.14 + '@angular/core': 21.2.17 - '@angular/build@21.2.13': - resolution: {integrity: sha512-Y9TDAaTQ+E5LScCKA/hPZmns/7Mpu6J2BiPj2cETA1xNjvgRpeb5Mh32KuhZb20NSFLvjpdnLuBTTtbym7hevw==} + '@angular/build@21.2.14': + resolution: {integrity: sha512-l8JB326iIwum2WmbopUUFdiuYsbHchix6MH8o6F6FA7LJr8QLTvipwwbw+Jx31/RE50WkGmzsZ1fBDw/cMbmUw==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} peerDependencies: '@angular/compiler': ^21.0.0 @@ -256,7 +257,7 @@ packages: '@angular/platform-browser': ^21.0.0 '@angular/platform-server': ^21.0.0 '@angular/service-worker': ^21.0.0 - '@angular/ssr': ^21.2.13 + '@angular/ssr': ^21.2.14 karma: ^6.4.0 less: ^4.2.0 ng-packagr: ^21.0.0 @@ -291,38 +292,38 @@ packages: vitest: optional: true - '@angular/cli@21.2.13': - resolution: {integrity: sha512-j1kOV/f0og/3xCwG7Y8RyPd6V7uYfX2NuvXbvN1mzgxLLN2mu6CTsvPg5l/9Pu9SJI3KOPRgDxWyuP3k8KuzMg==} + '@angular/cli@21.2.14': + resolution: {integrity: sha512-S8jExTjxPJILwpg2lu3DohSASVZ8DLhSNCmOe7z0qF9VskRSjC7SIQv1rq36tsJkenxuA72gjVOHZv+uSRT8HA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} hasBin: true - '@angular/common@21.2.14': - resolution: {integrity: sha512-J6K7cE7uKOKmg4+sxLeGfsmaYDjP5l1XCiMMI0WPT0t68uxLk8g3MzV5Trqfb6ZnRxWcfp9c4c+XxAvMBB7ymA==} + '@angular/common@21.2.17': + resolution: {integrity: sha512-hqAQxRfi5ldFE42suAXRcY+JCANrUh7fuSQ/DtZ7L896id5BT/exuv6dWNBC1PyAfQmRbpD5Pt6/pd+tNLyhDQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/core': 21.2.14 + '@angular/core': 21.2.17 rxjs: ^6.5.3 || ^7.4.0 - '@angular/compiler-cli@21.2.14': - resolution: {integrity: sha512-h+WQfPKFxaDfDhMqUUdOQ1TsDMccav8kLFERmKTRfD4MNOczSMpOMyeXJHCL0Rq4I8WDQvaBJGMG7DXRDefSog==} + '@angular/compiler-cli@21.2.17': + resolution: {integrity: sha512-KithZ3b0HBFH0NbUcswBcjpN9y09vLbarMD7qmGWTnGUBk4W8cn4sbT8zJyv9CRKg9ZcuUBeJYKUfUPn/u/5OQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} hasBin: true peerDependencies: - '@angular/compiler': 21.2.14 + '@angular/compiler': 21.2.17 typescript: '>=5.9 <6.1' peerDependenciesMeta: typescript: optional: true - '@angular/compiler@21.2.14': - resolution: {integrity: sha512-8mqgwRYfn2Z1vg/5YVt60dDBattnZL45nNJd2vTMwAiDTzhWhgKgRWKOeVL0aj2JqHeHiwuIlrLnz46acJMulQ==} + '@angular/compiler@21.2.17': + resolution: {integrity: sha512-p+NdjYiwAz9Zmu2yul0LlMXaFjMISVVa24+/MVMoKFeQeI82QE8jDywPlnOSHQHvdCcQVpS7saeEriZzX3JuBQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} - '@angular/core@21.2.14': - resolution: {integrity: sha512-Z1Ivjh7L2lT//8LA7vQ3tj7Rg6wl2XRA5kPSAukgn8u0Yu0XxG8NE8KG0Eypb3v9CEcbwATwpgnxzbJFZ8TFcw==} + '@angular/core@21.2.17': + resolution: {integrity: sha512-wYHpwIdnUnjQFOJJNqRcGx7LS3u64jT+R9L0TnMR/ViBM9dQgGYImlSikkftg2yrFCNo5aKRxhG2LLskQurVdg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/compiler': 21.2.14 + '@angular/compiler': 21.2.17 rxjs: ^6.5.3 || ^7.4.0 zone.js: ~0.15.0 || ~0.16.0 peerDependenciesMeta: @@ -331,49 +332,49 @@ packages: zone.js: optional: true - '@angular/forms@21.2.14': - resolution: {integrity: sha512-HQYIybyMt0CrI31rW6vXbiDsSM2DDtTcOVeT/nWDRNCoqBrREDg8rVsm2Y+fUMsiQVJNa6dCXPwvYhjzJ4r7ug==} + '@angular/forms@21.2.17': + resolution: {integrity: sha512-WKu8XeRSNZo+a+aDDZ3M5OtReF7KYqR/PmZ2l1lSf6N5EEAmc+Ky4aqbRhTL/mTSfHrO4+TDJ4C5A2tFmuwIeA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/common': 21.2.14 - '@angular/core': 21.2.14 - '@angular/platform-browser': 21.2.14 + '@angular/common': 21.2.17 + '@angular/core': 21.2.17 + '@angular/platform-browser': 21.2.17 rxjs: ^6.5.3 || ^7.4.0 - '@angular/localize@21.2.14': - resolution: {integrity: sha512-cVqQag+O8mIuH5Dz8Lw4uElWtFogr+xgUFbakI3QQAbnLaqeQaDqHvXE8VGkTmhGvEMnE0cvPn+rOQ/N5exzbw==} + '@angular/localize@21.2.17': + resolution: {integrity: sha512-CkiSHyag6W1cc2n8Y3sC4eYSqTqRslORU7DJnelEoJvh/2KM6/BmxxfjDlL6JcZURiiTPgxNjRgpb9zREj3elg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} hasBin: true peerDependencies: - '@angular/compiler': 21.2.14 - '@angular/compiler-cli': 21.2.14 + '@angular/compiler': 21.2.17 + '@angular/compiler-cli': 21.2.17 - '@angular/platform-browser-dynamic@21.2.14': - resolution: {integrity: sha512-m5U4zX8JFnxTAIGpsBXIAyefSmYqdORY/OfHC0aMmZovuFCbXXIYqYRQDBB7+YVNpSDSHllCrKEZFu/CC6dq3g==} + '@angular/platform-browser-dynamic@21.2.17': + resolution: {integrity: sha512-r/BU/T8bOTghP3fIXhzYf5wcMcAmhWnAFv3p4asCCPXomaktoas70wYcMaDH+pK1LAFBxLwzBWHm36MpFlTMFg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/common': 21.2.14 - '@angular/compiler': 21.2.14 - '@angular/core': 21.2.14 - '@angular/platform-browser': 21.2.14 + '@angular/common': 21.2.17 + '@angular/compiler': 21.2.17 + '@angular/core': 21.2.17 + '@angular/platform-browser': 21.2.17 - '@angular/platform-browser@21.2.14': - resolution: {integrity: sha512-34tBwxh86yN2YifBDhCesm6N+nn9WcbuXjRwfo0mTme15OZ/zt56yw7v1mcK3UFLegIIALtsIgpXXrPWWQoKkA==} + '@angular/platform-browser@21.2.17': + resolution: {integrity: sha512-ROdSliejY37g1EphYmweYdm5cHM8HY3X4tbWt4ubxmhTyYgfN3nxrxfGQ/n7Mz5tDY9VXVLIGDgjLOGYOo4uTQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/animations': 21.2.14 - '@angular/common': 21.2.14 - '@angular/core': 21.2.14 + '@angular/animations': 21.2.17 + '@angular/common': 21.2.17 + '@angular/core': 21.2.17 peerDependenciesMeta: '@angular/animations': optional: true - '@angular/service-worker@21.2.14': - resolution: {integrity: sha512-60DMV71QcaRtj3HwmV8Oz5zOKKudEyWourpsfpFptzF4hQ+7T7I4xSla1J0q/7b16Kwf44Ey90vCPlUrsMLVrA==} + '@angular/service-worker@21.2.17': + resolution: {integrity: sha512-6/uKwxBA3udngVHuIVqD8kdMV1whfym9ESB1UyjoNINx+2zj7A749X89tiV0TW2CvWpUYUE7VxpoapEiv5lvfw==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} hasBin: true peerDependencies: - '@angular/core': 21.2.14 + '@angular/core': 21.2.17 rxjs: ^6.5.3 || ^7.4.0 '@asamuzakjp/css-color@4.1.2': @@ -471,8 +472,8 @@ packages: '@csstools/css-parser-algorithms': ^4.0.0 '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-color-parser@4.1.1': - resolution: {integrity: sha512-eZ5XOtyhK+mggRafYUWzA0tvaYOFgdY8AkgQiCJF9qNAePnUo/zmsqqYubBBb3sQ8uNUaSKTY9s9klfRaAXL0g==} + '@csstools/css-color-parser@4.1.3': + resolution: {integrity: sha512-DOgvIPkikIOixQRlD4YF31VN6fLLUTdrzhfRbis8vm0kMTgIbEPX0Ip/YX9fOeV9iywAS4sUUbTclpan7yYP8Q==} engines: {node: '>=20.19.0'} peerDependencies: '@csstools/css-parser-algorithms': ^4.0.0 @@ -484,8 +485,8 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.4': - resolution: {integrity: sha512-wgsqt92b7C7tQhIdPNxj0n9zuUbQlvAuI1exyzeNrOKOi62SD7ren8zqszmpVREjAOqg8cD2FqYhQfAuKjk4sw==} + '@csstools/css-syntax-patches-for-csstree@1.1.5': + resolution: {integrity: sha512-oNjBvzLq2GPZtJphCjLqXow/cHySHSgtxvKZb7OqSZ/xHgw6NWNhfad+6AB9cLeVm6eA9d/qMll3JdEHjy6M+A==} peerDependencies: css-tree: ^3.2.1 peerDependenciesMeta: @@ -1119,8 +1120,8 @@ packages: resolution: {integrity: sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==} engines: {node: '>= 10'} - '@napi-rs/wasm-runtime@1.1.4': - resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} + '@napi-rs/wasm-runtime@1.1.5': + resolution: {integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==} peerDependencies: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 @@ -1370,146 +1371,146 @@ packages: '@rolldown/pluginutils@1.0.0-rc.4': resolution: {integrity: sha512-1BrrmTu0TWfOP1riA8uakjFc9bpIUGzVKETsOtzY39pPga8zELGDl8eu1Dx7/gjM5CAz14UknsUMpBO8L+YntQ==} - '@rollup/rollup-android-arm-eabi@4.60.4': - resolution: {integrity: sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==} + '@rollup/rollup-android-arm-eabi@4.61.1': + resolution: {integrity: sha512-JnBB8MdXj45cajvTuO5FmPlvFVJRQgvrz1uSEl3NwqFnReAPGwb8EanbGi4z2nRaqLzjJSv5/JmycoTKlRZxHA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.60.4': - resolution: {integrity: sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==} + '@rollup/rollup-android-arm64@4.61.1': + resolution: {integrity: sha512-Jx2g7iSjw4AOT0HDPHM9RV3GNjRXwybWtSFZiZAYUTjUwjVrYIwq3kBf+LnhqJlzXFAqTAh2F7IGI+O568exPw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.60.4': - resolution: {integrity: sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==} + '@rollup/rollup-darwin-arm64@4.61.1': + resolution: {integrity: sha512-0F1L/Z3Eqv8mT2n3dCpeO8GcTvHvVqkP5/t6DMsn0KzhYVcg+s7Ncl5DS8qjKYEeio6Az0Gt6nyBORay5qIlCA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.60.4': - resolution: {integrity: sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==} + '@rollup/rollup-darwin-x64@4.61.1': + resolution: {integrity: sha512-qLttcH871ujY4YcVfUSShhOw+CsoTatYz8gRbHO7Bb92QH059/P0y5do1KMs41fY0BpD2x4AJH/gID0zFiqVKQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.60.4': - resolution: {integrity: sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==} + '@rollup/rollup-freebsd-arm64@4.61.1': + resolution: {integrity: sha512-fUI4RapGE0Oh3mb8mgfvC1O2nU1RpDZUKnDQm3xB1Ipg7C2wTs5Kstz7G2uWK99a8S2yTMq8/P4uycwNa0nJyw==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.60.4': - resolution: {integrity: sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==} + '@rollup/rollup-freebsd-x64@4.61.1': + resolution: {integrity: sha512-H5YrdvJaDtI/U9/emrD4b++xkvp3y/JvOe4rizHbxvkyMfRS/CiRYdji+Pl8D0brEaNFWUh1drQxgAGIl6Xudw==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.60.4': - resolution: {integrity: sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==} + '@rollup/rollup-linux-arm-gnueabihf@4.61.1': + resolution: {integrity: sha512-Q8CBCCQtDFrYtXoeUXSrnFXKOnyUhx6bz+SkL6A0E7V8kAiCJ5pamq1WtbfpVGhR5TSpXY6ak3avmDc5fHTyJA==} cpu: [arm] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.60.4': - resolution: {integrity: sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==} + '@rollup/rollup-linux-arm-musleabihf@4.61.1': + resolution: {integrity: sha512-nwnhk1581l0FBVellGcVCAT0Oi06onEA3WB53sf01VO3I0UPBkMH9sXONYME2K0ovXcNayJfNtHfm6mpJElatQ==} cpu: [arm] os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.60.4': - resolution: {integrity: sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==} + '@rollup/rollup-linux-arm64-gnu@4.61.1': + resolution: {integrity: sha512-x5Xr49hwt3hdW75UOZm3395YwwzPyauktslv29KpWL/T+vVAzoT3azLcTWv0eMciBNrx+DYjH4paehHoLpPvpg==} cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.60.4': - resolution: {integrity: sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==} + '@rollup/rollup-linux-arm64-musl@4.61.1': + resolution: {integrity: sha512-unMS3H73DpaoPyyEVPjGKleM/s0mkmsauTENpw4INQY8y4+IuLNjkueQ5QCtC0D3N38Y38yhAU8OoZ20S2Tm6w==} cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.60.4': - resolution: {integrity: sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==} + '@rollup/rollup-linux-loong64-gnu@4.61.1': + resolution: {integrity: sha512-zNZzGRnAhwjFEYmvphJRV5XaQGjs62cCmeYYHUT//NbvEnHauw+I85nGG+SiVg5ld4GX8D1IbKIX+ozITQnhMQ==} cpu: [loong64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-loong64-musl@4.60.4': - resolution: {integrity: sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==} + '@rollup/rollup-linux-loong64-musl@4.61.1': + resolution: {integrity: sha512-LdpWGL8X209B2SIvWjqlc8VZgM6PKfontSerGepuldQmHYrAOtnMCXeJkxXGbC+PPZVOuu5czJo7fNV6aeW8rQ==} cpu: [loong64] os: [linux] libc: [musl] - '@rollup/rollup-linux-ppc64-gnu@4.60.4': - resolution: {integrity: sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==} + '@rollup/rollup-linux-ppc64-gnu@4.61.1': + resolution: {integrity: sha512-EC5kTtNaNGOmbMGqar8dvJy6y/hg99GAwjfBz++pxZhQATXGcRjd6c5en5wcbru0vkRmiMGsQKdMJOOf6sza4g==} cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.60.4': - resolution: {integrity: sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==} + '@rollup/rollup-linux-ppc64-musl@4.61.1': + resolution: {integrity: sha512-8hiwp6D4acEcNK78I4rP0/XtS1sknWIAMJBPdR4l6zUtyTm5KiTDr5bXmWt4foY7nAN7AThDHgkLIEZOWKbzWw==} cpu: [ppc64] os: [linux] libc: [musl] - '@rollup/rollup-linux-riscv64-gnu@4.60.4': - resolution: {integrity: sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==} + '@rollup/rollup-linux-riscv64-gnu@4.61.1': + resolution: {integrity: sha512-10dh/h/BqA7DuMPWSxkR8uks18FRwnwOEqr5zOTEl+NOwP/OMzKX8OFR/Of9xxDA7D5qef1Nzar5WDD2kCCr1g==} cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.60.4': - resolution: {integrity: sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==} + '@rollup/rollup-linux-riscv64-musl@4.61.1': + resolution: {integrity: sha512-YKJ5lg35DP17gcAOggnihe+APw9HLyj1Xn7gsmGumBJAUDa6NGXNixJzmkWLhcK9TOuuyQjdamzvJefkO7qHZQ==} cpu: [riscv64] os: [linux] libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.60.4': - resolution: {integrity: sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==} + '@rollup/rollup-linux-s390x-gnu@4.61.1': + resolution: {integrity: sha512-Mlil5G2Jj6a7B3LWGctg+XPL9vdXYuzCtNXfxOQ0nPjc2m6ueUktocPGH9bnAM0bNRKb/bAWTujUU7IJQdQA+g==} cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.60.4': - resolution: {integrity: sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==} + '@rollup/rollup-linux-x64-gnu@4.61.1': + resolution: {integrity: sha512-bVWIOIk6pV01p4CdUbPP7CJ/434z+OooYjDuFcR+44N35YvKUC66G8MGnvcWx5mWKW3g61J+t74l3Kj15Kwn2Q==} cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.60.4': - resolution: {integrity: sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==} + '@rollup/rollup-linux-x64-musl@4.61.1': + resolution: {integrity: sha512-qy5pBvZbqNFheBz61R1rzsezjm0J7O2oNGoWtGoY89SZYLUfxAJTBAqDChqAIdB4rCiIbi9nF7yZ83GnNiLwSw==} cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-openbsd-x64@4.60.4': - resolution: {integrity: sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==} + '@rollup/rollup-openbsd-x64@4.61.1': + resolution: {integrity: sha512-E83TXjI4zm0+5f2qO+UOudaCYIhYwpJ5jq6YCZNIZ+6CbfhKrkAGezeiASBL9ElxAxFsRS9ZhESv8mfnj6TKeg==} cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.60.4': - resolution: {integrity: sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==} + '@rollup/rollup-openharmony-arm64@4.61.1': + resolution: {integrity: sha512-fbWnKqVkjrJN38vNe3ahkbk6iejS/3b0Nt7EEtPpE6RBacZcGXNKbzfHN3GUUlXOPghUg0j6XUGrtjX9z1sIvA==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.60.4': - resolution: {integrity: sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==} + '@rollup/rollup-win32-arm64-msvc@4.61.1': + resolution: {integrity: sha512-ArMl38iVAbk0New1ogihQNY6iphLi4ZaRsa037gUzv5yeKPY8TD3Dmy4x2RNC1VztU/uqm+G+/RwFrSka3Oy2g==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.60.4': - resolution: {integrity: sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==} + '@rollup/rollup-win32-ia32-msvc@4.61.1': + resolution: {integrity: sha512-0mYtjHS9ucAbcATycCNK9IGBk/cCe/ma7EmSLGZdsxnOA8cjRIyU04wDpVAD9NiOfLUR9KTxdiO53uOkherqjQ==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.60.4': - resolution: {integrity: sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==} + '@rollup/rollup-win32-x64-gnu@4.61.1': + resolution: {integrity: sha512-gK1iCEPfpoSG9wfBihXxvBMi8ZfcWffYkEsC/Eih+iFENTaewvNcrEQ69lIOWYO5pePHKLHHO7nq5AILGO/HQQ==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.60.4': - resolution: {integrity: sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==} + '@rollup/rollup-win32-x64-msvc@4.61.1': + resolution: {integrity: sha512-X+zaP2x+j4RXGfbp/seSoRHWnPxzApilDszisZxbYH5C/jTxFhCtDNdPGZb9lJyYPs24wGxruPF7Y+sIXt9Gzw==} cpu: [x64] os: [win32] - '@schematics/angular@21.2.13': - resolution: {integrity: sha512-e5guslSLKbb3PJ6gUuVqM+V9xgn68cJkG1IyBohho34shbpOeoWW2eYdWQQjxvn0KUdgEhYSRBluBamCHngaUA==} + '@schematics/angular@21.2.14': + resolution: {integrity: sha512-rIEdtNTdCCTwuo7B4tMoq5qmbLXdBgmW6Ays1hyno//4OE+HFtvlWZd+hl6KceEyN00IcZ2HRaPnfd71E1JnoA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} '@sigstore/bundle@4.0.0': @@ -1577,17 +1578,14 @@ packages: '@types/esrecurse@4.3.1': resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/node@25.9.1': - resolution: {integrity: sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==} + '@types/node@25.9.3': + resolution: {integrity: sha512-603BddQMv3pUcr4U2dhujk83N2tTDVr/34wII2B6bJy6g+8WD6yUb11jszNs0gdi4PesVWl7ABt8nYMVpnLUcg==} '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} @@ -1613,8 +1611,8 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.60.0': - resolution: {integrity: sha512-aZu74NNKJeUWqCjDddzdiKaS82dgYgV/vmf+Ui3ZdZejmgfXR/q+pRumgobnQ2cCJTgGTWp4ypiwsuofFubavg==} + '@typescript-eslint/project-service@8.61.0': + resolution: {integrity: sha512-DV42F7MLJO6Rax7SK1yg43tcnEfGUrurSpSxKuVX+a3RCTzBlH3fuxprrOJXKCJGAaw82xXocikJ0uQaqwXgGA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' @@ -1623,8 +1621,8 @@ packages: resolution: {integrity: sha512-a0TTJk4HXMkfpFkL9/WaGTNuv7JWfFTQFJd6zS9dVAjKsojmv9HT55xzbEpnZoY+VUb+YXLMp+ihMLz/UlZfDg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.60.0': - resolution: {integrity: sha512-pFzqhllJMs+jghLQWzV00ds39xLzuyqPSev5pd8f4Ir0rtKR3ZLUB4/4dhjOFighWb9larvtfJvqL+4yKDI3Xw==} + '@typescript-eslint/scope-manager@8.61.0': + resolution: {integrity: sha512-IWdXFHFSb6mlC3HPc7QsLDm5zYEbUla6trDEHf32D3/dnuUyXd87plScSNXSbm0/RxMvObpI17sv/EDTGrGZkA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/tsconfig-utils@8.47.0': @@ -1633,8 +1631,8 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/tsconfig-utils@8.60.0': - resolution: {integrity: sha512-BZPR3RGYlAXnly6ymAxfkVn5rCbZzQNou0rxv3GfWZ8cTQp+hhVd73khbGLAd8k1TlAPLISH337M+tAgAnaJDQ==} + '@typescript-eslint/tsconfig-utils@8.61.0': + resolution: {integrity: sha512-O5Amvdv9ztMpxpf+vmFULGG78IE6Qwdr3bCGvqwG4nwc9H2qXkOYJJnRbRHyMkQTjv1d03olqwwwzHLMqpFePQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' @@ -1650,8 +1648,8 @@ packages: resolution: {integrity: sha512-nHAE6bMKsizhA2uuYZbEbmp5z2UpffNrPEqiKIeN7VsV6UY/roxanWfoRrf6x/k9+Obf+GQdkm0nPU+vnMXo9A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.60.0': - resolution: {integrity: sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA==} + '@typescript-eslint/types@8.61.0': + resolution: {integrity: sha512-9QTQpZ5Iin4CdIodfbDQFSeiSJKidgYJYug1P9CC2xWgUTvlmixViqDZNciMjwLBZyJnG4tGmPl97rVAFb1AJg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/typescript-estree@8.47.0': @@ -1660,8 +1658,8 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/typescript-estree@8.60.0': - resolution: {integrity: sha512-3AcZNBGMClm6CXDyo8kYvVGT/sx29sS0oBsIb9oZI2gunA4Vm2M3YHzRLPvsUBBsl+yB5FPtltq7gGH0iTlp9g==} + '@typescript-eslint/typescript-estree@8.61.0': + resolution: {integrity: sha512-42zatd5qSvvcV1JdDBCLxYRznvP4eIHpPoZXdkPFnAmanA4FuZ5dibSnCBggY8hQnqajPpoGjXFdZ7fIJKQnlA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' @@ -1673,8 +1671,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.60.0': - resolution: {integrity: sha512-HtXuPfrHTyBDkameWpl+vJb1Uevu2tznAyahM1Oc4AENidCLTPiZDWIo4GfcxNdC/RcfGcadzzkqbRG87dUrQA==} + '@typescript-eslint/utils@8.61.0': + resolution: {integrity: sha512-3bzFt7ImFMW/jVYwJamDoe/dMOdFLSC6pom6rRjdh4SZJEYupyMzem8e7vKZLclLfpHjlwSAXOUxtKxGXUiLqA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -1684,8 +1682,8 @@ packages: resolution: {integrity: sha512-SIV3/6eftCy1bNzCQoPmbWsRLujS8t5iDIZ4spZOBHqrM+yfX2ogg8Tt3PDTAVKw3sSCiUgg30uOAvK2r9zGjQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.60.0': - resolution: {integrity: sha512-9WI52t8ZGLVGrPMBet25yAftqY/n95+zmoUUtJBBQTKDSKUu7OsPTroT2op7U9JatkoRccL0YkWDNMFfC4Sjxg==} + '@typescript-eslint/visitor-keys@8.61.0': + resolution: {integrity: sha512-QVLZu3ZPQEE+HICQyAMZ2yLQhxf0meY/wx6Hx14YcTNj13JB3qHlX3lJ02L3fLGHgERRH71kvYDwiXIguT3AjQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@vitejs/plugin-basic-ssl@2.1.4': @@ -1694,11 +1692,11 @@ packages: peerDependencies: vite: ^6.0.0 || ^7.0.0 - '@vitest/expect@4.1.7': - resolution: {integrity: sha512-1R+tw0ortHEbZDGMymm+pN7/AFQ/RkFFdtd7EN+VBpynKmLbP8A3rpEXdshBJ7+8hQ9zBJh/i1s0yKNtxAnU7w==} + '@vitest/expect@4.1.8': + resolution: {integrity: sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ==} - '@vitest/mocker@4.1.7': - resolution: {integrity: sha512-vY7nuamKgfvpA1Koa3oYIw/k7D6kZnpGyNMZW8loow2bsBYla1TFdqTaXncWdRn4pgwNs+90RhnXhJScDwQeJA==} + '@vitest/mocker@4.1.8': + resolution: {integrity: sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -1708,20 +1706,20 @@ packages: vite: optional: true - '@vitest/pretty-format@4.1.7': - resolution: {integrity: sha512-umgCarTOYQWIaDMvGDRZij+6b9oVeLIyJzfN+AS88e0ZOU3QTgNNSTtjQOpcvWr3np1N0j4WgZj+sb3oYBDscw==} + '@vitest/pretty-format@4.1.8': + resolution: {integrity: sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA==} - '@vitest/runner@4.1.7': - resolution: {integrity: sha512-BapjmAQ2aI78WdMEfeUWivnfVzB+VPGwWRQcJE0OUq7qEeEcBsCSf+0T5iREBNE5nBb4wA5Ya0W6IA+sghdEFw==} + '@vitest/runner@4.1.8': + resolution: {integrity: sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg==} - '@vitest/snapshot@4.1.7': - resolution: {integrity: sha512-ZacLzja+TmJeZ1h14xW2FB/WpeimUD3haBXQPyJqxvo8jQTmfeA8zv58mtjN2C7EHXZDYVcVYdYmAxjkWVvKCw==} + '@vitest/snapshot@4.1.8': + resolution: {integrity: sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ==} - '@vitest/spy@4.1.7': - resolution: {integrity: sha512-kbkI5LMWakyuTIvs6fUJ5qdIVb1XVKsYJAT4OJ938cHMROYMSfmoQdZy0aaAnjbbc8F61vkoTqz/Az+/HiIu5Q==} + '@vitest/spy@4.1.8': + resolution: {integrity: sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA==} - '@vitest/utils@4.1.7': - resolution: {integrity: sha512-T532WBu791cBxJlCl6SO+J14l81DQx6uQHm1bQbmCDY7nqlEIgkza/UFnSBNaUtSf41unldDFjdOBYEQC4b5Hw==} + '@vitest/utils@4.1.8': + resolution: {integrity: sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg==} '@yarnpkg/lockfile@1.1.0': resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} @@ -1827,8 +1825,8 @@ packages: resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} engines: {node: ^4.5.0 || >= 5.9} - baseline-browser-mapping@2.10.32: - resolution: {integrity: sha512-wbPvpyjJPC0zdfdKXxqEL3Ea+bOMD/87X4lftiJkkaBiuG6ALQy1SLmEd7BSmVCuwCQsBrCamgBoLyfFDD1EPg==} + baseline-browser-mapping@2.10.35: + resolution: {integrity: sha512-honAfLBde0HAFLdNyBEfuuENkF6zR+ozxqxa/2zJKHBe1qzLqyTSeRKpdPEHAP03rlDGyQOPnCSxnVpVqQo9Mg==} engines: {node: '>=6.0.0'} hasBin: true @@ -1893,8 +1891,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001793: - resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==} + caniuse-lite@1.0.30001797: + resolution: {integrity: sha512-l8xKG+gwAIExZGl9FrF7KUwuOmk6wbEPC9Xoy/RtnWv1XG0Q4LFlagaLpUv3Kiza3W/wm27zy0yWJEieYKAP6w==} chai@6.2.2: resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} @@ -2055,8 +2053,8 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.363: - resolution: {integrity: sha512-VjUKPyWzGnT1fujlkEGC/BvN70Hh70KXtAqcmniXviYlJC/ivcT+BWGPyxWVbJZLfvtKR6dqg1L7T7pgAMBtWA==} + electron-to-chromium@1.5.371: + resolution: {integrity: sha512-e9htk9mAYL6AzmkEhSvVVw7IWGSBJ/Bqdn2eRyRLrj1g6sncN4WbFt5qnILYoCktktr45pyjIrOiRvBThQ808w==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -2350,12 +2348,12 @@ packages: resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} engines: {node: '>= 0.4'} - hasown@2.0.3: - resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} engines: {node: '>= 0.4'} - hono@4.12.23: - resolution: {integrity: sha512-eIaZ9qDgu7XV0pxOCrg7/WhnQ6Ivm22UcxhXx/A3dcbqbbYgBEkc6e/J/s7j2tS96zoB0S9VBdLwQNCWwUo4LA==} + hono@4.12.25: + resolution: {integrity: sha512-2NFaIyNVgJmBs/ecmtGzlmluTFs5cHEWGTdu0t1HBwYzoGXOL5nUQBRMXsXWla5i4KkG//QMzVP88m1+I3fdAQ==} engines: {node: '>=16.9.0'} hosted-git-info@9.0.3: @@ -2400,8 +2398,8 @@ packages: resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} - immutable@5.1.5: - resolution: {integrity: sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==} + immutable@5.1.6: + resolution: {integrity: sha512-q1swsS8K7L8usSHuOqF2TAoCCkonYz0SG38wLAggaa4Wml70zixIvt2ql4coQ2C2B3hTjltJry4r6bULwgAXLQ==} import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} @@ -2481,8 +2479,8 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + js-yaml@4.2.0: + resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==} hasBin: true jsdom@27.4.0: @@ -2671,8 +2669,8 @@ packages: resolution: {integrity: sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==} hasBin: true - msgpackr@1.11.12: - resolution: {integrity: sha512-RBdJ1Un7yGlXWajrkxcSa93nvQ0w4zBf60c0yYv7YtBelP8H2FA7XsfBbMHtXKXUMUxH7zV3Zuozh+kUQWhHvg==} + msgpackr@1.12.1: + resolution: {integrity: sha512-4EUH9tQHnMmEgzW/MdAP0KIfa1T9AF+htl0ffe2n5vb2EKn9y2co8ccpgWko6S52Jy1PQZKwRnx5/KkYjtd9MQ==} mute-stream@2.0.0: resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} @@ -2717,13 +2715,13 @@ packages: resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==} hasBin: true - node-gyp@12.3.0: - resolution: {integrity: sha512-QNcUWM+HgJplcPzBvFBZ9VXacyGZ4+VTOb80PwWR+TlVzoHbRKULNEzpRsnaoxG3Wzr7Qh7BYxGDU3CbKib2Yg==} + node-gyp@12.4.0: + resolution: {integrity: sha512-OMcPNvqTCFUnNaBlmdgq+lfNqY7gTiSmNRDjY3uAXRyudeKZEZxu3CLtjMQrx4zZxCX2b/mpNqTtwuCJgXhHkw==} engines: {node: ^20.17.0 || >=22.9.0} hasBin: true - node-releases@2.0.46: - resolution: {integrity: sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==} + node-releases@2.0.47: + resolution: {integrity: sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==} engines: {node: '>=18'} nopt@9.0.0: @@ -2770,8 +2768,9 @@ packages: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} - obug@2.1.1: - resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + obug@2.1.2: + resolution: {integrity: sha512-AWGB9WFcRXOQs48Z/udjI5ZcZMHXwX8XPByNpOydgcGsDLIzjGizhoMWJyKAWze7AVW/2W1i+/gPX4YtKe5cyg==} + engines: {node: '>=12.20.0'} on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} @@ -2953,8 +2952,8 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - rollup@4.60.4: - resolution: {integrity: sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==} + rollup@4.61.1: + resolution: {integrity: sha512-I4KW6iuRpuu2uHBLraZ1wNZe0DP7lnRha+VJ9tNaYVaVgKhW0aI3h4RYnoRPeql0flHm/Co55b7snEDcOfOJrA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -2994,8 +2993,8 @@ packages: engines: {node: '>=10'} hasBin: true - semver@7.8.1: - resolution: {integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==} + semver@7.8.4: + resolution: {integrity: sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==} engines: {node: '>=10'} hasBin: true @@ -3030,8 +3029,8 @@ packages: resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} engines: {node: '>= 0.4'} - side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + side-channel@1.1.1: + resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} engines: {node: '>= 0.4'} siginfo@2.0.0: @@ -3153,34 +3152,34 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - tar@7.5.15: - resolution: {integrity: sha512-dzGK0boVlC4W5QFuQN1EFSl3bIDYsk7Tj40U6eIBnK2k/8ml7TZ5agbI5j5+qnoVcAA+rNtBml8SEiLxZpNqRQ==} + tar@7.5.16: + resolution: {integrity: sha512-56adEpPMouktRlBLXiaYFFzZ/3+JXa8P9n7WbR+ibIjtviN55mEaOkiysCnPnWm+7kkui1Dn8J9l+g6zV8731w==} engines: {node: '>=18'} tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - tinyexec@1.2.2: - resolution: {integrity: sha512-M/Q0B2cp4K7kynaT/vnED1j8TlLY+Pp7C6Wl2bl/7u/F0mUVwdyOpwomQb8JpYLitHUssAJRmLZdMCGsrx7i+g==} + tinyexec@1.2.4: + resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} engines: {node: '>=18'} tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} - tinyglobby@0.2.16: - resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} tinyrainbow@3.1.0: resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} engines: {node: '>=14.0.0'} - tldts-core@7.4.0: - resolution: {integrity: sha512-/mb9kRld+x1sIMXxWNOAp5m6C+D4GrAORWlJkOJ5dElvxdN1eutz/o7qHLp9gFvDF4Y3/L2xeScoxz6AbEo8rQ==} + tldts-core@7.4.2: + resolution: {integrity: sha512-nwEyF4vl4RSJjwSjBUmOSxc3BFPoIFdlRthJ6e+5v9P3bHNsoD06UjuqMUspqp7vsEZ1beaHi1km+optiE17yA==} - tldts@7.4.0: - resolution: {integrity: sha512-yHBe+zVfzNZ3QfTPW/Z6KK1G2t340gFjMHqI/4KKSt/abzYydzuCnpqdaF5gCCABby+9Yfbj59oR5F2Fd5CBzg==} + tldts@7.4.2: + resolution: {integrity: sha512-kCwffuaH8ntKtygnWe1b4BJKWiCUH30n5KfoTr6IchcXOwR7chAOFJxFrH3vjANafUYrIA4a7SDL+nn7SiR4Sw==} hasBin: true to-regex-range@5.0.1: @@ -3304,20 +3303,20 @@ packages: yaml: optional: true - vitest@4.1.7: - resolution: {integrity: sha512-flYyaFd2CgoCoU+0UKt3pxksgC+S02iTDN0n3LtqaMeXsI9SBcdNujc2k0DeFLzUn/0k538yNjOSdwgCqcrwJA==} + vitest@4.1.8: + resolution: {integrity: sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.7 - '@vitest/browser-preview': 4.1.7 - '@vitest/browser-webdriverio': 4.1.7 - '@vitest/coverage-istanbul': 4.1.7 - '@vitest/coverage-v8': 4.1.7 - '@vitest/ui': 4.1.7 + '@vitest/browser-playwright': 4.1.8 + '@vitest/browser-preview': 4.1.8 + '@vitest/browser-webdriverio': 4.1.8 + '@vitest/coverage-istanbul': 4.1.8 + '@vitest/coverage-v8': 4.1.8 + '@vitest/ui': 4.1.8 happy-dom: '*' jsdom: '*' vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -3575,14 +3574,14 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@angular-devkit/architect@0.2102.13(chokidar@5.0.0)': + '@angular-devkit/architect@0.2102.14(chokidar@5.0.0)': dependencies: - '@angular-devkit/core': 21.2.13(chokidar@5.0.0) + '@angular-devkit/core': 21.2.14(chokidar@5.0.0) rxjs: 7.8.2 transitivePeerDependencies: - chokidar - '@angular-devkit/core@21.2.13(chokidar@5.0.0)': + '@angular-devkit/core@21.2.14(chokidar@5.0.0)': dependencies: ajv: 8.18.0 ajv-formats: 3.0.1(ajv@8.18.0) @@ -3593,9 +3592,9 @@ snapshots: optionalDependencies: chokidar: 5.0.0 - '@angular-devkit/schematics@21.2.13(chokidar@5.0.0)': + '@angular-devkit/schematics@21.2.14(chokidar@5.0.0)': dependencies: - '@angular-devkit/core': 21.2.13(chokidar@5.0.0) + '@angular-devkit/core': 21.2.14(chokidar@5.0.0) jsonc-parser: 3.3.1 magic-string: 0.30.21 ora: 9.3.0 @@ -3603,11 +3602,11 @@ snapshots: transitivePeerDependencies: - chokidar - '@angular-eslint/builder@21.1.0(@angular/cli@21.2.13(@types/node@25.9.1)(chokidar@5.0.0))(chokidar@5.0.0)(eslint@9.39.4)(typescript@5.9.3)': + '@angular-eslint/builder@21.1.0(@angular/cli@21.2.14(@types/node@25.9.3)(chokidar@5.0.0))(chokidar@5.0.0)(eslint@9.39.4)(typescript@5.9.3)': dependencies: - '@angular-devkit/architect': 0.2102.13(chokidar@5.0.0) - '@angular-devkit/core': 21.2.13(chokidar@5.0.0) - '@angular/cli': 21.2.13(@types/node@25.9.1)(chokidar@5.0.0) + '@angular-devkit/architect': 0.2102.14(chokidar@5.0.0) + '@angular-devkit/core': 21.2.14(chokidar@5.0.0) + '@angular/cli': 21.2.14(@types/node@25.9.3)(chokidar@5.0.0) eslint: 9.39.4 typescript: 5.9.3 transitivePeerDependencies: @@ -3615,34 +3614,34 @@ snapshots: '@angular-eslint/bundled-angular-compiler@21.1.0': {} - '@angular-eslint/eslint-plugin-template@21.1.0(@angular-eslint/template-parser@21.1.0(eslint@9.39.4)(typescript@5.9.3))(@typescript-eslint/types@8.60.0)(@typescript-eslint/utils@8.60.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3)': + '@angular-eslint/eslint-plugin-template@21.1.0(@angular-eslint/template-parser@21.1.0(eslint@9.39.4)(typescript@5.9.3))(@typescript-eslint/types@8.61.0)(@typescript-eslint/utils@8.61.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3)': dependencies: '@angular-eslint/bundled-angular-compiler': 21.1.0 '@angular-eslint/template-parser': 21.1.0(eslint@9.39.4)(typescript@5.9.3) - '@angular-eslint/utils': 21.1.0(@typescript-eslint/utils@8.60.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/utils': 8.60.0(eslint@9.39.4)(typescript@5.9.3) + '@angular-eslint/utils': 21.1.0(@typescript-eslint/utils@8.61.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4)(typescript@5.9.3) aria-query: 5.3.2 axobject-query: 4.1.0 eslint: 9.39.4 typescript: 5.9.3 - '@angular-eslint/eslint-plugin@21.1.0(@typescript-eslint/utils@8.60.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3)': + '@angular-eslint/eslint-plugin@21.1.0(@typescript-eslint/utils@8.61.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3)': dependencies: '@angular-eslint/bundled-angular-compiler': 21.1.0 - '@angular-eslint/utils': 21.1.0(@typescript-eslint/utils@8.60.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) - '@typescript-eslint/utils': 8.60.0(eslint@9.39.4)(typescript@5.9.3) + '@angular-eslint/utils': 21.1.0(@typescript-eslint/utils@8.61.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4)(typescript@5.9.3) eslint: 9.39.4 ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 - '@angular-eslint/schematics@21.1.0(@angular-eslint/template-parser@21.1.0(eslint@9.39.4)(typescript@5.9.3))(@angular/cli@21.2.13(@types/node@25.9.1)(chokidar@5.0.0))(@typescript-eslint/types@8.60.0)(@typescript-eslint/utils@8.60.0(eslint@9.39.4)(typescript@5.9.3))(chokidar@5.0.0)(eslint@9.39.4)(typescript@5.9.3)': + '@angular-eslint/schematics@21.1.0(@angular-eslint/template-parser@21.1.0(eslint@9.39.4)(typescript@5.9.3))(@angular/cli@21.2.14(@types/node@25.9.3)(chokidar@5.0.0))(@typescript-eslint/types@8.61.0)(@typescript-eslint/utils@8.61.0(eslint@9.39.4)(typescript@5.9.3))(chokidar@5.0.0)(eslint@9.39.4)(typescript@5.9.3)': dependencies: - '@angular-devkit/core': 21.2.13(chokidar@5.0.0) - '@angular-devkit/schematics': 21.2.13(chokidar@5.0.0) - '@angular-eslint/eslint-plugin': 21.1.0(@typescript-eslint/utils@8.60.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) - '@angular-eslint/eslint-plugin-template': 21.1.0(@angular-eslint/template-parser@21.1.0(eslint@9.39.4)(typescript@5.9.3))(@typescript-eslint/types@8.60.0)(@typescript-eslint/utils@8.60.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) - '@angular/cli': 21.2.13(@types/node@25.9.1)(chokidar@5.0.0) + '@angular-devkit/core': 21.2.14(chokidar@5.0.0) + '@angular-devkit/schematics': 21.2.14(chokidar@5.0.0) + '@angular-eslint/eslint-plugin': 21.1.0(@typescript-eslint/utils@8.61.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) + '@angular-eslint/eslint-plugin-template': 21.1.0(@angular-eslint/template-parser@21.1.0(eslint@9.39.4)(typescript@5.9.3))(@typescript-eslint/types@8.61.0)(@typescript-eslint/utils@8.61.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) + '@angular/cli': 21.2.14(@types/node@25.9.3)(chokidar@5.0.0) ignore: 7.0.5 semver: 7.7.3 strip-json-comments: 3.1.1 @@ -3661,29 +3660,29 @@ snapshots: eslint-scope: 9.1.2 typescript: 5.9.3 - '@angular-eslint/utils@21.1.0(@typescript-eslint/utils@8.60.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3)': + '@angular-eslint/utils@21.1.0(@typescript-eslint/utils@8.61.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3)': dependencies: '@angular-eslint/bundled-angular-compiler': 21.1.0 - '@typescript-eslint/utils': 8.60.0(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4)(typescript@5.9.3) eslint: 9.39.4 typescript: 5.9.3 - '@angular/animations@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))': + '@angular/animations@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))': dependencies: - '@angular/core': 21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0) + '@angular/core': 21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0) tslib: 2.8.1 - '@angular/build@21.2.13(@angular/compiler-cli@21.2.14(@angular/compiler@21.2.14)(typescript@5.9.3))(@angular/compiler@21.2.14)(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/localize@21.2.14(@angular/compiler-cli@21.2.14(@angular/compiler@21.2.14)(typescript@5.9.3))(@angular/compiler@21.2.14))(@angular/platform-browser@21.2.14(@angular/animations@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/service-worker@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@25.9.1)(chokidar@5.0.0)(postcss@8.5.15)(tslib@2.8.1)(typescript@5.9.3)(vitest@4.1.7(@types/node@25.9.1)(jsdom@27.4.0)(vite@7.3.2(@types/node@25.9.1)(sass@1.97.3)))': + '@angular/build@21.2.14(@angular/compiler-cli@21.2.17(@angular/compiler@21.2.17)(typescript@5.9.3))(@angular/compiler@21.2.17)(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/localize@21.2.17(@angular/compiler-cli@21.2.17(@angular/compiler@21.2.17)(typescript@5.9.3))(@angular/compiler@21.2.17))(@angular/platform-browser@21.2.17(@angular/animations@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/service-worker@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@types/node@25.9.3)(chokidar@5.0.0)(postcss@8.5.15)(tslib@2.8.1)(typescript@5.9.3)(vitest@4.1.8(@types/node@25.9.3)(jsdom@27.4.0)(vite@7.3.2(@types/node@25.9.3)(sass@1.97.3)))': dependencies: '@ampproject/remapping': 2.3.0 - '@angular-devkit/architect': 0.2102.13(chokidar@5.0.0) - '@angular/compiler': 21.2.14 - '@angular/compiler-cli': 21.2.14(@angular/compiler@21.2.14)(typescript@5.9.3) + '@angular-devkit/architect': 0.2102.14(chokidar@5.0.0) + '@angular/compiler': 21.2.17 + '@angular/compiler-cli': 21.2.17(@angular/compiler@21.2.17)(typescript@5.9.3) '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-split-export-declaration': 7.24.7 - '@inquirer/confirm': 5.1.21(@types/node@25.9.1) - '@vitejs/plugin-basic-ssl': 2.1.4(vite@7.3.2(@types/node@25.9.1)(sass@1.97.3)) + '@inquirer/confirm': 5.1.21(@types/node@25.9.3) + '@vitejs/plugin-basic-ssl': 2.1.4(vite@7.3.2(@types/node@25.9.3)(sass@1.97.3)) beasties: 0.4.1 browserslist: 4.28.2 esbuild: 0.27.3 @@ -3704,16 +3703,16 @@ snapshots: tslib: 2.8.1 typescript: 5.9.3 undici: 7.24.4 - vite: 7.3.2(@types/node@25.9.1)(sass@1.97.3) + vite: 7.3.2(@types/node@25.9.3)(sass@1.97.3) watchpack: 2.5.1 optionalDependencies: - '@angular/core': 21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0) - '@angular/localize': 21.2.14(@angular/compiler-cli@21.2.14(@angular/compiler@21.2.14)(typescript@5.9.3))(@angular/compiler@21.2.14) - '@angular/platform-browser': 21.2.14(@angular/animations@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)) - '@angular/service-worker': 21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) + '@angular/core': 21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0) + '@angular/localize': 21.2.17(@angular/compiler-cli@21.2.17(@angular/compiler@21.2.17)(typescript@5.9.3))(@angular/compiler@21.2.17) + '@angular/platform-browser': 21.2.17(@angular/animations@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)) + '@angular/service-worker': 21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) lmdb: 3.5.1 postcss: 8.5.15 - vitest: 4.1.7(@types/node@25.9.1)(jsdom@27.4.0)(vite@7.3.2(@types/node@25.9.1)(sass@1.97.3)) + vitest: 4.1.8(@types/node@25.9.3)(jsdom@27.4.0)(vite@7.3.2(@types/node@25.9.3)(sass@1.97.3)) transitivePeerDependencies: - '@emnapi/core' - '@emnapi/runtime' @@ -3729,15 +3728,15 @@ snapshots: - tsx - yaml - '@angular/cli@21.2.13(@types/node@25.9.1)(chokidar@5.0.0)': + '@angular/cli@21.2.14(@types/node@25.9.3)(chokidar@5.0.0)': dependencies: - '@angular-devkit/architect': 0.2102.13(chokidar@5.0.0) - '@angular-devkit/core': 21.2.13(chokidar@5.0.0) - '@angular-devkit/schematics': 21.2.13(chokidar@5.0.0) - '@inquirer/prompts': 7.10.1(@types/node@25.9.1) - '@listr2/prompt-adapter-inquirer': 3.0.5(@inquirer/prompts@7.10.1(@types/node@25.9.1))(@types/node@25.9.1)(listr2@9.0.5) + '@angular-devkit/architect': 0.2102.14(chokidar@5.0.0) + '@angular-devkit/core': 21.2.14(chokidar@5.0.0) + '@angular-devkit/schematics': 21.2.14(chokidar@5.0.0) + '@inquirer/prompts': 7.10.1(@types/node@25.9.3) + '@listr2/prompt-adapter-inquirer': 3.0.5(@inquirer/prompts@7.10.1(@types/node@25.9.3))(@types/node@25.9.3)(listr2@9.0.5) '@modelcontextprotocol/sdk': 1.26.0(zod@4.3.6) - '@schematics/angular': 21.2.13(chokidar@5.0.0) + '@schematics/angular': 21.2.14(chokidar@5.0.0) '@yarnpkg/lockfile': 1.1.0 algoliasearch: 5.48.1 ini: 6.0.0 @@ -3755,21 +3754,21 @@ snapshots: - chokidar - supports-color - '@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2)': + '@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2)': dependencies: - '@angular/core': 21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0) + '@angular/core': 21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/compiler-cli@21.2.14(@angular/compiler@21.2.14)(typescript@5.9.3)': + '@angular/compiler-cli@21.2.17(@angular/compiler@21.2.17)(typescript@5.9.3)': dependencies: - '@angular/compiler': 21.2.14 + '@angular/compiler': 21.2.17 '@babel/core': 7.29.0 '@jridgewell/sourcemap-codec': 1.5.5 chokidar: 5.0.0 convert-source-map: 1.9.0 reflect-metadata: 0.2.2 - semver: 7.8.1 + semver: 7.8.4 tslib: 2.8.1 yargs: 18.0.0 optionalDependencies: @@ -3777,64 +3776,64 @@ snapshots: transitivePeerDependencies: - supports-color - '@angular/compiler@21.2.14': + '@angular/compiler@21.2.17': dependencies: tslib: 2.8.1 - '@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)': + '@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)': dependencies: rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - '@angular/compiler': 21.2.14 + '@angular/compiler': 21.2.17 zone.js: 0.15.0 - '@angular/forms@21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@21.2.14(@angular/animations@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2)': + '@angular/forms@21.2.17(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@21.2.17(@angular/animations@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2)': dependencies: - '@angular/common': 21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) - '@angular/core': 21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0) - '@angular/platform-browser': 21.2.14(@angular/animations@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)) + '@angular/common': 21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) + '@angular/core': 21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0) + '@angular/platform-browser': 21.2.17(@angular/animations@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)) '@standard-schema/spec': 1.1.0 rxjs: 7.8.2 tslib: 2.8.1 - '@angular/localize@21.2.14(@angular/compiler-cli@21.2.14(@angular/compiler@21.2.14)(typescript@5.9.3))(@angular/compiler@21.2.14)': + '@angular/localize@21.2.17(@angular/compiler-cli@21.2.17(@angular/compiler@21.2.17)(typescript@5.9.3))(@angular/compiler@21.2.17)': dependencies: - '@angular/compiler': 21.2.14 - '@angular/compiler-cli': 21.2.14(@angular/compiler@21.2.14)(typescript@5.9.3) + '@angular/compiler': 21.2.17 + '@angular/compiler-cli': 21.2.17(@angular/compiler@21.2.17)(typescript@5.9.3) '@babel/core': 7.29.0 '@types/babel__core': 7.20.5 - tinyglobby: 0.2.16 + tinyglobby: 0.2.17 yargs: 18.0.0 transitivePeerDependencies: - supports-color - '@angular/platform-browser-dynamic@21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/compiler@21.2.14)(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@21.2.14(@angular/animations@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))': + '@angular/platform-browser-dynamic@21.2.17(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/compiler@21.2.17)(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@21.2.17(@angular/animations@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))': dependencies: - '@angular/common': 21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) - '@angular/compiler': 21.2.14 - '@angular/core': 21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0) - '@angular/platform-browser': 21.2.14(@angular/animations@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)) + '@angular/common': 21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) + '@angular/compiler': 21.2.17 + '@angular/core': 21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0) + '@angular/platform-browser': 21.2.17(@angular/animations@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)) tslib: 2.8.1 - '@angular/platform-browser@21.2.14(@angular/animations@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))': + '@angular/platform-browser@21.2.17(@angular/animations@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))': dependencies: - '@angular/common': 21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) - '@angular/core': 21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0) + '@angular/common': 21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) + '@angular/core': 21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0) tslib: 2.8.1 optionalDependencies: - '@angular/animations': 21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)) + '@angular/animations': 21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)) - '@angular/service-worker@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2)': + '@angular/service-worker@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2)': dependencies: - '@angular/core': 21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0) + '@angular/core': 21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0) rxjs: 7.8.2 tslib: 2.8.1 '@asamuzakjp/css-color@4.1.2': dependencies: '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/css-color-parser': 4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.3(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 lru-cache: 11.5.1 @@ -3964,7 +3963,7 @@ snapshots: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/css-color-parser@4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + '@csstools/css-color-parser@4.1.3(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': dependencies: '@csstools/color-helpers': 6.0.2 '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) @@ -3975,7 +3974,7 @@ snapshots: dependencies: '@csstools/css-tokenizer': 4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.4(css-tree@3.2.1)': + '@csstools/css-syntax-patches-for-csstree@1.1.5(css-tree@3.2.1)': optionalDependencies: css-tree: 3.2.1 @@ -4106,7 +4105,7 @@ snapshots: globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.1 - js-yaml: 4.1.1 + js-yaml: 4.2.0 minimatch: 3.1.5 strip-json-comments: 3.1.1 transitivePeerDependencies: @@ -4123,9 +4122,9 @@ snapshots: '@exodus/bytes@1.15.1': {} - '@fortawesome/angular-fontawesome@4.0.0(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))': + '@fortawesome/angular-fontawesome@4.0.0(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))': dependencies: - '@angular/core': 21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0) + '@angular/core': 21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0) '@fortawesome/fontawesome-svg-core': 7.2.0 tslib: 2.8.1 @@ -4152,9 +4151,9 @@ snapshots: '@harperfast/extended-iterable@1.0.3': optional: true - '@hono/node-server@1.19.14(hono@4.12.23)': + '@hono/node-server@1.19.14(hono@4.12.25)': dependencies: - hono: 4.12.23 + hono: 4.12.25 '@humanfs/core@0.19.2': dependencies: @@ -4174,128 +4173,128 @@ snapshots: '@inquirer/ansi@1.0.2': {} - '@inquirer/checkbox@4.3.2(@types/node@25.9.1)': + '@inquirer/checkbox@4.3.2(@types/node@25.9.3)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@25.9.1) + '@inquirer/core': 10.3.2(@types/node@25.9.3) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@25.9.1) + '@inquirer/type': 3.0.10(@types/node@25.9.3) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 - '@inquirer/confirm@5.1.21(@types/node@25.9.1)': + '@inquirer/confirm@5.1.21(@types/node@25.9.3)': dependencies: - '@inquirer/core': 10.3.2(@types/node@25.9.1) - '@inquirer/type': 3.0.10(@types/node@25.9.1) + '@inquirer/core': 10.3.2(@types/node@25.9.3) + '@inquirer/type': 3.0.10(@types/node@25.9.3) optionalDependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 - '@inquirer/core@10.3.2(@types/node@25.9.1)': + '@inquirer/core@10.3.2(@types/node@25.9.3)': dependencies: '@inquirer/ansi': 1.0.2 '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@25.9.1) + '@inquirer/type': 3.0.10(@types/node@25.9.3) cli-width: 4.1.0 mute-stream: 2.0.0 signal-exit: 4.1.0 wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 - '@inquirer/editor@4.2.23(@types/node@25.9.1)': + '@inquirer/editor@4.2.23(@types/node@25.9.3)': dependencies: - '@inquirer/core': 10.3.2(@types/node@25.9.1) - '@inquirer/external-editor': 1.0.3(@types/node@25.9.1) - '@inquirer/type': 3.0.10(@types/node@25.9.1) + '@inquirer/core': 10.3.2(@types/node@25.9.3) + '@inquirer/external-editor': 1.0.3(@types/node@25.9.3) + '@inquirer/type': 3.0.10(@types/node@25.9.3) optionalDependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 - '@inquirer/expand@4.0.23(@types/node@25.9.1)': + '@inquirer/expand@4.0.23(@types/node@25.9.3)': dependencies: - '@inquirer/core': 10.3.2(@types/node@25.9.1) - '@inquirer/type': 3.0.10(@types/node@25.9.1) + '@inquirer/core': 10.3.2(@types/node@25.9.3) + '@inquirer/type': 3.0.10(@types/node@25.9.3) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 - '@inquirer/external-editor@1.0.3(@types/node@25.9.1)': + '@inquirer/external-editor@1.0.3(@types/node@25.9.3)': dependencies: chardet: 2.1.1 iconv-lite: 0.7.2 optionalDependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 '@inquirer/figures@1.0.15': {} - '@inquirer/input@4.3.1(@types/node@25.9.1)': + '@inquirer/input@4.3.1(@types/node@25.9.3)': dependencies: - '@inquirer/core': 10.3.2(@types/node@25.9.1) - '@inquirer/type': 3.0.10(@types/node@25.9.1) + '@inquirer/core': 10.3.2(@types/node@25.9.3) + '@inquirer/type': 3.0.10(@types/node@25.9.3) optionalDependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 - '@inquirer/number@3.0.23(@types/node@25.9.1)': + '@inquirer/number@3.0.23(@types/node@25.9.3)': dependencies: - '@inquirer/core': 10.3.2(@types/node@25.9.1) - '@inquirer/type': 3.0.10(@types/node@25.9.1) + '@inquirer/core': 10.3.2(@types/node@25.9.3) + '@inquirer/type': 3.0.10(@types/node@25.9.3) optionalDependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 - '@inquirer/password@4.0.23(@types/node@25.9.1)': + '@inquirer/password@4.0.23(@types/node@25.9.3)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@25.9.1) - '@inquirer/type': 3.0.10(@types/node@25.9.1) + '@inquirer/core': 10.3.2(@types/node@25.9.3) + '@inquirer/type': 3.0.10(@types/node@25.9.3) optionalDependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 - '@inquirer/prompts@7.10.1(@types/node@25.9.1)': + '@inquirer/prompts@7.10.1(@types/node@25.9.3)': dependencies: - '@inquirer/checkbox': 4.3.2(@types/node@25.9.1) - '@inquirer/confirm': 5.1.21(@types/node@25.9.1) - '@inquirer/editor': 4.2.23(@types/node@25.9.1) - '@inquirer/expand': 4.0.23(@types/node@25.9.1) - '@inquirer/input': 4.3.1(@types/node@25.9.1) - '@inquirer/number': 3.0.23(@types/node@25.9.1) - '@inquirer/password': 4.0.23(@types/node@25.9.1) - '@inquirer/rawlist': 4.1.11(@types/node@25.9.1) - '@inquirer/search': 3.2.2(@types/node@25.9.1) - '@inquirer/select': 4.4.2(@types/node@25.9.1) + '@inquirer/checkbox': 4.3.2(@types/node@25.9.3) + '@inquirer/confirm': 5.1.21(@types/node@25.9.3) + '@inquirer/editor': 4.2.23(@types/node@25.9.3) + '@inquirer/expand': 4.0.23(@types/node@25.9.3) + '@inquirer/input': 4.3.1(@types/node@25.9.3) + '@inquirer/number': 3.0.23(@types/node@25.9.3) + '@inquirer/password': 4.0.23(@types/node@25.9.3) + '@inquirer/rawlist': 4.1.11(@types/node@25.9.3) + '@inquirer/search': 3.2.2(@types/node@25.9.3) + '@inquirer/select': 4.4.2(@types/node@25.9.3) optionalDependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 - '@inquirer/rawlist@4.1.11(@types/node@25.9.1)': + '@inquirer/rawlist@4.1.11(@types/node@25.9.3)': dependencies: - '@inquirer/core': 10.3.2(@types/node@25.9.1) - '@inquirer/type': 3.0.10(@types/node@25.9.1) + '@inquirer/core': 10.3.2(@types/node@25.9.3) + '@inquirer/type': 3.0.10(@types/node@25.9.3) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 - '@inquirer/search@3.2.2(@types/node@25.9.1)': + '@inquirer/search@3.2.2(@types/node@25.9.3)': dependencies: - '@inquirer/core': 10.3.2(@types/node@25.9.1) + '@inquirer/core': 10.3.2(@types/node@25.9.3) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@25.9.1) + '@inquirer/type': 3.0.10(@types/node@25.9.3) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 - '@inquirer/select@4.4.2(@types/node@25.9.1)': + '@inquirer/select@4.4.2(@types/node@25.9.3)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@25.9.1) + '@inquirer/core': 10.3.2(@types/node@25.9.3) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@25.9.1) + '@inquirer/type': 3.0.10(@types/node@25.9.3) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 - '@inquirer/type@3.0.10(@types/node@25.9.1)': + '@inquirer/type@3.0.10(@types/node@25.9.3)': optionalDependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 '@isaacs/fs-minipass@4.0.1': dependencies: @@ -4322,10 +4321,10 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@listr2/prompt-adapter-inquirer@3.0.5(@inquirer/prompts@7.10.1(@types/node@25.9.1))(@types/node@25.9.1)(listr2@9.0.5)': + '@listr2/prompt-adapter-inquirer@3.0.5(@inquirer/prompts@7.10.1(@types/node@25.9.3))(@types/node@25.9.3)(listr2@9.0.5)': dependencies: - '@inquirer/prompts': 7.10.1(@types/node@25.9.1) - '@inquirer/type': 3.0.10(@types/node@25.9.1) + '@inquirer/prompts': 7.10.1(@types/node@25.9.3) + '@inquirer/type': 3.0.10(@types/node@25.9.3) listr2: 9.0.5 transitivePeerDependencies: - '@types/node' @@ -4353,7 +4352,7 @@ snapshots: '@modelcontextprotocol/sdk@1.26.0(zod@4.3.6)': dependencies: - '@hono/node-server': 1.19.14(hono@4.12.23) + '@hono/node-server': 1.19.14(hono@4.12.25) ajv: 8.20.0 ajv-formats: 3.0.1(ajv@8.20.0) content-type: 1.0.5 @@ -4363,7 +4362,7 @@ snapshots: eventsource-parser: 3.1.0 express: 5.2.1 express-rate-limit: 8.5.2(express@5.2.1) - hono: 4.12.23 + hono: 4.12.25 jose: 6.2.3 json-schema-typed: 8.0.2 pkce-challenge: 5.0.1 @@ -4463,28 +4462,28 @@ snapshots: '@napi-rs/nice-win32-x64-msvc': 1.1.1 optional: true - '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 '@tybys/wasm-util': 0.10.2 optional: true - '@ng-bootstrap/ng-bootstrap@20.0.0(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/forms@21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@21.2.14(@angular/animations@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2))(@angular/localize@21.2.14(@angular/compiler-cli@21.2.14(@angular/compiler@21.2.14)(typescript@5.9.3))(@angular/compiler@21.2.14))(@popperjs/core@2.11.8)(rxjs@7.8.2)': + '@ng-bootstrap/ng-bootstrap@20.0.0(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/forms@21.2.17(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@21.2.17(@angular/animations@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2))(@angular/localize@21.2.17(@angular/compiler-cli@21.2.17(@angular/compiler@21.2.17)(typescript@5.9.3))(@angular/compiler@21.2.17))(@popperjs/core@2.11.8)(rxjs@7.8.2)': dependencies: - '@angular/common': 21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) - '@angular/core': 21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0) - '@angular/forms': 21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@21.2.14(@angular/animations@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2) - '@angular/localize': 21.2.14(@angular/compiler-cli@21.2.14(@angular/compiler@21.2.14)(typescript@5.9.3))(@angular/compiler@21.2.14) + '@angular/common': 21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) + '@angular/core': 21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0) + '@angular/forms': 21.2.17(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@21.2.17(@angular/animations@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2) + '@angular/localize': 21.2.17(@angular/compiler-cli@21.2.17(@angular/compiler@21.2.17)(typescript@5.9.3))(@angular/compiler@21.2.17) '@popperjs/core': 2.11.8 rxjs: 7.8.2 tslib: 2.8.1 - '@ng-select/ng-select@21.8.2(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/forms@21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@21.2.14(@angular/animations@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2))': + '@ng-select/ng-select@21.8.2(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/forms@21.2.17(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@21.2.17(@angular/animations@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2))': dependencies: - '@angular/common': 21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) - '@angular/core': 21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0) - '@angular/forms': 21.2.14(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@21.2.14(@angular/animations@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2) + '@angular/common': 21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) + '@angular/core': 21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0) + '@angular/forms': 21.2.17(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(@angular/platform-browser@21.2.17(@angular/animations@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)))(rxjs@7.8.2) tslib: 2.8.1 '@nodelib/fs.scandir@2.1.5': @@ -4552,7 +4551,7 @@ snapshots: '@npmcli/node-gyp': 5.0.0 '@npmcli/package-json': 7.0.5 '@npmcli/promise-spawn': 9.0.1 - node-gyp: 12.3.0 + node-gyp: 12.4.0 proc-log: 6.1.0 '@oxc-project/types@0.113.0': {} @@ -4652,7 +4651,7 @@ snapshots: '@rolldown/binding-wasm32-wasi@1.0.0-rc.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': dependencies: - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) transitivePeerDependencies: - '@emnapi/core' - '@emnapi/runtime' @@ -4666,85 +4665,85 @@ snapshots: '@rolldown/pluginutils@1.0.0-rc.4': {} - '@rollup/rollup-android-arm-eabi@4.60.4': + '@rollup/rollup-android-arm-eabi@4.61.1': optional: true - '@rollup/rollup-android-arm64@4.60.4': + '@rollup/rollup-android-arm64@4.61.1': optional: true - '@rollup/rollup-darwin-arm64@4.60.4': + '@rollup/rollup-darwin-arm64@4.61.1': optional: true - '@rollup/rollup-darwin-x64@4.60.4': + '@rollup/rollup-darwin-x64@4.61.1': optional: true - '@rollup/rollup-freebsd-arm64@4.60.4': + '@rollup/rollup-freebsd-arm64@4.61.1': optional: true - '@rollup/rollup-freebsd-x64@4.60.4': + '@rollup/rollup-freebsd-x64@4.61.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.60.4': + '@rollup/rollup-linux-arm-gnueabihf@4.61.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.60.4': + '@rollup/rollup-linux-arm-musleabihf@4.61.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.60.4': + '@rollup/rollup-linux-arm64-gnu@4.61.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.60.4': + '@rollup/rollup-linux-arm64-musl@4.61.1': optional: true - '@rollup/rollup-linux-loong64-gnu@4.60.4': + '@rollup/rollup-linux-loong64-gnu@4.61.1': optional: true - '@rollup/rollup-linux-loong64-musl@4.60.4': + '@rollup/rollup-linux-loong64-musl@4.61.1': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.60.4': + '@rollup/rollup-linux-ppc64-gnu@4.61.1': optional: true - '@rollup/rollup-linux-ppc64-musl@4.60.4': + '@rollup/rollup-linux-ppc64-musl@4.61.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.60.4': + '@rollup/rollup-linux-riscv64-gnu@4.61.1': optional: true - '@rollup/rollup-linux-riscv64-musl@4.60.4': + '@rollup/rollup-linux-riscv64-musl@4.61.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.60.4': + '@rollup/rollup-linux-s390x-gnu@4.61.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.60.4': + '@rollup/rollup-linux-x64-gnu@4.61.1': optional: true - '@rollup/rollup-linux-x64-musl@4.60.4': + '@rollup/rollup-linux-x64-musl@4.61.1': optional: true - '@rollup/rollup-openbsd-x64@4.60.4': + '@rollup/rollup-openbsd-x64@4.61.1': optional: true - '@rollup/rollup-openharmony-arm64@4.60.4': + '@rollup/rollup-openharmony-arm64@4.61.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.60.4': + '@rollup/rollup-win32-arm64-msvc@4.61.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.60.4': + '@rollup/rollup-win32-ia32-msvc@4.61.1': optional: true - '@rollup/rollup-win32-x64-gnu@4.60.4': + '@rollup/rollup-win32-x64-gnu@4.61.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.60.4': + '@rollup/rollup-win32-x64-msvc@4.61.1': optional: true - '@schematics/angular@21.2.13(chokidar@5.0.0)': + '@schematics/angular@21.2.14(chokidar@5.0.0)': dependencies: - '@angular-devkit/core': 21.2.13(chokidar@5.0.0) - '@angular-devkit/schematics': 21.2.13(chokidar@5.0.0) + '@angular-devkit/core': 21.2.14(chokidar@5.0.0) + '@angular-devkit/schematics': 21.2.14(chokidar@5.0.0) jsonc-parser: 3.3.1 transitivePeerDependencies: - chokidar @@ -4825,25 +4824,23 @@ snapshots: '@types/cors@2.8.19': dependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 '@types/deep-eql@4.0.2': {} '@types/esrecurse@4.3.1': {} - '@types/estree@1.0.8': {} - '@types/estree@1.0.9': {} '@types/json-schema@7.0.15': {} - '@types/node@25.9.1': + '@types/node@25.9.3': dependencies: undici-types: 7.24.6 '@types/ws@8.18.1': dependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 '@typescript-eslint/eslint-plugin@8.47.0(@typescript-eslint/parser@8.47.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3)': dependencies: @@ -4883,10 +4880,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.60.0(typescript@5.9.3)': + '@typescript-eslint/project-service@8.61.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.60.0(typescript@5.9.3) - '@typescript-eslint/types': 8.60.0 + '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@5.9.3) + '@typescript-eslint/types': 8.61.0 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: @@ -4897,16 +4894,16 @@ snapshots: '@typescript-eslint/types': 8.47.0 '@typescript-eslint/visitor-keys': 8.47.0 - '@typescript-eslint/scope-manager@8.60.0': + '@typescript-eslint/scope-manager@8.61.0': dependencies: - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/visitor-keys': 8.60.0 + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/visitor-keys': 8.61.0 '@typescript-eslint/tsconfig-utils@8.47.0(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/tsconfig-utils@8.60.0(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.61.0(typescript@5.9.3)': dependencies: typescript: 5.9.3 @@ -4924,7 +4921,7 @@ snapshots: '@typescript-eslint/types@8.47.0': {} - '@typescript-eslint/types@8.60.0': {} + '@typescript-eslint/types@8.61.0': {} '@typescript-eslint/typescript-estree@8.47.0(typescript@5.9.3)': dependencies: @@ -4936,22 +4933,22 @@ snapshots: fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.9 - semver: 7.8.1 + semver: 7.8.4 ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.60.0(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.61.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.60.0(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.60.0(typescript@5.9.3) - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/visitor-keys': 8.60.0 + '@typescript-eslint/project-service': 8.61.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@5.9.3) + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/visitor-keys': 8.61.0 debug: 4.4.3 minimatch: 10.2.5 - semver: 7.8.1 - tinyglobby: 0.2.16 + semver: 7.8.4 + tinyglobby: 0.2.17 ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: @@ -4968,12 +4965,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.60.0(eslint@9.39.4)(typescript@5.9.3)': + '@typescript-eslint/utils@8.61.0(eslint@9.39.4)(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) - '@typescript-eslint/scope-manager': 8.60.0 - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/typescript-estree': 8.60.0(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.61.0 + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/typescript-estree': 8.61.0(typescript@5.9.3) eslint: 9.39.4 typescript: 5.9.3 transitivePeerDependencies: @@ -4984,53 +4981,53 @@ snapshots: '@typescript-eslint/types': 8.47.0 eslint-visitor-keys: 4.2.1 - '@typescript-eslint/visitor-keys@8.60.0': + '@typescript-eslint/visitor-keys@8.61.0': dependencies: - '@typescript-eslint/types': 8.60.0 + '@typescript-eslint/types': 8.61.0 eslint-visitor-keys: 5.0.1 - '@vitejs/plugin-basic-ssl@2.1.4(vite@7.3.2(@types/node@25.9.1)(sass@1.97.3))': + '@vitejs/plugin-basic-ssl@2.1.4(vite@7.3.2(@types/node@25.9.3)(sass@1.97.3))': dependencies: - vite: 7.3.2(@types/node@25.9.1)(sass@1.97.3) + vite: 7.3.2(@types/node@25.9.3)(sass@1.97.3) - '@vitest/expect@4.1.7': + '@vitest/expect@4.1.8': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.1.7 - '@vitest/utils': 4.1.7 + '@vitest/spy': 4.1.8 + '@vitest/utils': 4.1.8 chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.7(vite@7.3.2(@types/node@25.9.1)(sass@1.97.3))': + '@vitest/mocker@4.1.8(vite@7.3.2(@types/node@25.9.3)(sass@1.97.3))': dependencies: - '@vitest/spy': 4.1.7 + '@vitest/spy': 4.1.8 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.2(@types/node@25.9.1)(sass@1.97.3) + vite: 7.3.2(@types/node@25.9.3)(sass@1.97.3) - '@vitest/pretty-format@4.1.7': + '@vitest/pretty-format@4.1.8': dependencies: tinyrainbow: 3.1.0 - '@vitest/runner@4.1.7': + '@vitest/runner@4.1.8': dependencies: - '@vitest/utils': 4.1.7 + '@vitest/utils': 4.1.8 pathe: 2.0.3 - '@vitest/snapshot@4.1.7': + '@vitest/snapshot@4.1.8': dependencies: - '@vitest/pretty-format': 4.1.7 - '@vitest/utils': 4.1.7 + '@vitest/pretty-format': 4.1.8 + '@vitest/utils': 4.1.8 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.1.7': {} + '@vitest/spy@4.1.8': {} - '@vitest/utils@4.1.7': + '@vitest/utils@4.1.8': dependencies: - '@vitest/pretty-format': 4.1.7 + '@vitest/pretty-format': 4.1.8 convert-source-map: 2.0.0 tinyrainbow: 3.1.0 @@ -5102,18 +5099,18 @@ snapshots: '@algolia/requester-fetch': 5.48.1 '@algolia/requester-node-http': 5.48.1 - angular-eslint@21.1.0(@angular/cli@21.2.13(@types/node@25.9.1)(chokidar@5.0.0))(chokidar@5.0.0)(eslint@9.39.4)(typescript-eslint@8.47.0(eslint@9.39.4)(typescript@5.9.3))(typescript@5.9.3): + angular-eslint@21.1.0(@angular/cli@21.2.14(@types/node@25.9.3)(chokidar@5.0.0))(chokidar@5.0.0)(eslint@9.39.4)(typescript-eslint@8.47.0(eslint@9.39.4)(typescript@5.9.3))(typescript@5.9.3): dependencies: - '@angular-devkit/core': 21.2.13(chokidar@5.0.0) - '@angular-devkit/schematics': 21.2.13(chokidar@5.0.0) - '@angular-eslint/builder': 21.1.0(@angular/cli@21.2.13(@types/node@25.9.1)(chokidar@5.0.0))(chokidar@5.0.0)(eslint@9.39.4)(typescript@5.9.3) - '@angular-eslint/eslint-plugin': 21.1.0(@typescript-eslint/utils@8.60.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) - '@angular-eslint/eslint-plugin-template': 21.1.0(@angular-eslint/template-parser@21.1.0(eslint@9.39.4)(typescript@5.9.3))(@typescript-eslint/types@8.60.0)(@typescript-eslint/utils@8.60.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) - '@angular-eslint/schematics': 21.1.0(@angular-eslint/template-parser@21.1.0(eslint@9.39.4)(typescript@5.9.3))(@angular/cli@21.2.13(@types/node@25.9.1)(chokidar@5.0.0))(@typescript-eslint/types@8.60.0)(@typescript-eslint/utils@8.60.0(eslint@9.39.4)(typescript@5.9.3))(chokidar@5.0.0)(eslint@9.39.4)(typescript@5.9.3) + '@angular-devkit/core': 21.2.14(chokidar@5.0.0) + '@angular-devkit/schematics': 21.2.14(chokidar@5.0.0) + '@angular-eslint/builder': 21.1.0(@angular/cli@21.2.14(@types/node@25.9.3)(chokidar@5.0.0))(chokidar@5.0.0)(eslint@9.39.4)(typescript@5.9.3) + '@angular-eslint/eslint-plugin': 21.1.0(@typescript-eslint/utils@8.61.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) + '@angular-eslint/eslint-plugin-template': 21.1.0(@angular-eslint/template-parser@21.1.0(eslint@9.39.4)(typescript@5.9.3))(@typescript-eslint/types@8.61.0)(@typescript-eslint/utils@8.61.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) + '@angular-eslint/schematics': 21.1.0(@angular-eslint/template-parser@21.1.0(eslint@9.39.4)(typescript@5.9.3))(@angular/cli@21.2.14(@types/node@25.9.3)(chokidar@5.0.0))(@typescript-eslint/types@8.61.0)(@typescript-eslint/utils@8.61.0(eslint@9.39.4)(typescript@5.9.3))(chokidar@5.0.0)(eslint@9.39.4)(typescript@5.9.3) '@angular-eslint/template-parser': 21.1.0(eslint@9.39.4)(typescript@5.9.3) - '@angular/cli': 21.2.13(@types/node@25.9.1)(chokidar@5.0.0) - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/utils': 8.60.0(eslint@9.39.4)(typescript@5.9.3) + '@angular/cli': 21.2.14(@types/node@25.9.3)(chokidar@5.0.0) + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4)(typescript@5.9.3) eslint: 9.39.4 typescript: 5.9.3 typescript-eslint: 8.47.0(eslint@9.39.4)(typescript@5.9.3) @@ -5149,7 +5146,7 @@ snapshots: base64id@2.0.0: {} - baseline-browser-mapping@2.10.32: {} + baseline-browser-mapping@2.10.35: {} beasties@0.4.1: dependencies: @@ -5206,10 +5203,10 @@ snapshots: browserslist@4.28.2: dependencies: - baseline-browser-mapping: 2.10.32 - caniuse-lite: 1.0.30001793 - electron-to-chromium: 1.5.363 - node-releases: 2.0.46 + baseline-browser-mapping: 2.10.35 + caniuse-lite: 1.0.30001797 + electron-to-chromium: 1.5.371 + node-releases: 2.0.47 update-browserslist-db: 1.2.3(browserslist@4.28.2) buffer-from@1.1.2: {} @@ -5241,7 +5238,7 @@ snapshots: callsites@3.1.0: {} - caniuse-lite@1.0.30001793: {} + caniuse-lite@1.0.30001797: {} chai@6.2.2: {} @@ -5338,7 +5335,7 @@ snapshots: cssstyle@5.3.7: dependencies: '@asamuzakjp/css-color': 4.1.2 - '@csstools/css-syntax-patches-for-csstree': 1.1.4(css-tree@3.2.1) + '@csstools/css-syntax-patches-for-csstree': 1.1.5(css-tree@3.2.1) css-tree: 3.2.1 lru-cache: 11.5.1 @@ -5386,7 +5383,7 @@ snapshots: ee-first@1.1.1: {} - electron-to-chromium@1.5.363: {} + electron-to-chromium@1.5.371: {} emoji-regex@10.6.0: {} @@ -5411,7 +5408,7 @@ snapshots: engine.io@6.6.8: dependencies: '@types/cors': 2.8.19 - '@types/node': 25.9.1 + '@types/node': 25.9.3 '@types/ws': 8.18.1 accepts: 1.3.8 base64id: 2.0.0 @@ -5699,7 +5696,7 @@ snapshots: get-proto: 1.0.1 gopd: 1.2.0 has-symbols: 1.1.0 - hasown: 2.0.3 + hasown: 2.0.4 math-intrinsics: 1.1.0 get-proto@1.0.1: @@ -5735,11 +5732,11 @@ snapshots: has-symbols@1.1.0: {} - hasown@2.0.3: + hasown@2.0.4: dependencies: function-bind: 1.1.2 - hono@4.12.23: {} + hono@4.12.25: {} hosted-git-info@9.0.3: dependencies: @@ -5794,7 +5791,7 @@ snapshots: ignore@7.0.5: {} - immutable@5.1.5: {} + immutable@5.1.6: {} import-fresh@3.3.1: dependencies: @@ -5853,7 +5850,7 @@ snapshots: js-tokens@4.0.0: {} - js-yaml@4.1.1: + js-yaml@4.2.0: dependencies: argparse: 2.0.1 @@ -5926,7 +5923,7 @@ snapshots: lmdb@3.5.1: dependencies: '@harperfast/extended-iterable': 1.0.3 - msgpackr: 1.11.12 + msgpackr: 1.12.1 node-addon-api: 6.1.0 node-gyp-build-optional-packages: 5.2.2 ordered-binary: 1.6.1 @@ -6078,7 +6075,7 @@ snapshots: '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.4 optional: true - msgpackr@1.11.12: + msgpackr@1.12.1: optionalDependencies: msgpackr-extract: 3.0.4 optional: true @@ -6093,16 +6090,16 @@ snapshots: negotiator@1.0.0: {} - ngx-cookie-service@21.3.1(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0)): + ngx-cookie-service@21.3.1(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0)): dependencies: - '@angular/common': 21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) - '@angular/core': 21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0) + '@angular/common': 21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) + '@angular/core': 21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0) tslib: 2.8.1 - ngx-socket-io@4.10.0(@angular/common@21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2): + ngx-socket-io@4.10.0(@angular/common@21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2))(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2): dependencies: - '@angular/common': 21.2.14(@angular/core@21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) - '@angular/core': 21.2.14(@angular/compiler@21.2.14)(rxjs@7.8.2)(zone.js@0.15.0) + '@angular/common': 21.2.17(@angular/core@21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0))(rxjs@7.8.2) + '@angular/core': 21.2.17(@angular/compiler@21.2.17)(rxjs@7.8.2)(zone.js@0.15.0) core-js: 3.49.0 reflect-metadata: 0.2.2 rxjs: 7.8.2 @@ -6125,7 +6122,7 @@ snapshots: detect-libc: 2.1.2 optional: true - node-gyp@12.3.0: + node-gyp@12.4.0: dependencies: env-paths: 2.2.1 exponential-backoff: 3.1.3 @@ -6133,12 +6130,12 @@ snapshots: nopt: 9.0.0 proc-log: 6.1.0 semver: 7.7.4 - tar: 7.5.15 - tinyglobby: 0.2.16 + tar: 7.5.16 + tinyglobby: 0.2.17 undici: 6.26.0 which: 6.0.1 - node-releases@2.0.46: {} + node-releases@2.0.47: {} nopt@9.0.0: dependencies: @@ -6194,7 +6191,7 @@ snapshots: object-inspect@1.13.4: {} - obug@2.1.1: {} + obug@2.1.2: {} on-finished@2.4.1: dependencies: @@ -6259,7 +6256,7 @@ snapshots: promise-retry: 2.0.1 sigstore: 4.1.1 ssri: 13.0.1 - tar: 7.5.15 + tar: 7.5.16 transitivePeerDependencies: - supports-color @@ -6338,7 +6335,7 @@ snapshots: qs@6.15.2: dependencies: - side-channel: 1.1.0 + side-channel: 1.1.1 queue-microtask@1.2.3: {} @@ -6394,35 +6391,35 @@ snapshots: - '@emnapi/core' - '@emnapi/runtime' - rollup@4.60.4: + rollup@4.61.1: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.60.4 - '@rollup/rollup-android-arm64': 4.60.4 - '@rollup/rollup-darwin-arm64': 4.60.4 - '@rollup/rollup-darwin-x64': 4.60.4 - '@rollup/rollup-freebsd-arm64': 4.60.4 - '@rollup/rollup-freebsd-x64': 4.60.4 - '@rollup/rollup-linux-arm-gnueabihf': 4.60.4 - '@rollup/rollup-linux-arm-musleabihf': 4.60.4 - '@rollup/rollup-linux-arm64-gnu': 4.60.4 - '@rollup/rollup-linux-arm64-musl': 4.60.4 - '@rollup/rollup-linux-loong64-gnu': 4.60.4 - '@rollup/rollup-linux-loong64-musl': 4.60.4 - '@rollup/rollup-linux-ppc64-gnu': 4.60.4 - '@rollup/rollup-linux-ppc64-musl': 4.60.4 - '@rollup/rollup-linux-riscv64-gnu': 4.60.4 - '@rollup/rollup-linux-riscv64-musl': 4.60.4 - '@rollup/rollup-linux-s390x-gnu': 4.60.4 - '@rollup/rollup-linux-x64-gnu': 4.60.4 - '@rollup/rollup-linux-x64-musl': 4.60.4 - '@rollup/rollup-openbsd-x64': 4.60.4 - '@rollup/rollup-openharmony-arm64': 4.60.4 - '@rollup/rollup-win32-arm64-msvc': 4.60.4 - '@rollup/rollup-win32-ia32-msvc': 4.60.4 - '@rollup/rollup-win32-x64-gnu': 4.60.4 - '@rollup/rollup-win32-x64-msvc': 4.60.4 + '@rollup/rollup-android-arm-eabi': 4.61.1 + '@rollup/rollup-android-arm64': 4.61.1 + '@rollup/rollup-darwin-arm64': 4.61.1 + '@rollup/rollup-darwin-x64': 4.61.1 + '@rollup/rollup-freebsd-arm64': 4.61.1 + '@rollup/rollup-freebsd-x64': 4.61.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.61.1 + '@rollup/rollup-linux-arm-musleabihf': 4.61.1 + '@rollup/rollup-linux-arm64-gnu': 4.61.1 + '@rollup/rollup-linux-arm64-musl': 4.61.1 + '@rollup/rollup-linux-loong64-gnu': 4.61.1 + '@rollup/rollup-linux-loong64-musl': 4.61.1 + '@rollup/rollup-linux-ppc64-gnu': 4.61.1 + '@rollup/rollup-linux-ppc64-musl': 4.61.1 + '@rollup/rollup-linux-riscv64-gnu': 4.61.1 + '@rollup/rollup-linux-riscv64-musl': 4.61.1 + '@rollup/rollup-linux-s390x-gnu': 4.61.1 + '@rollup/rollup-linux-x64-gnu': 4.61.1 + '@rollup/rollup-linux-x64-musl': 4.61.1 + '@rollup/rollup-openbsd-x64': 4.61.1 + '@rollup/rollup-openharmony-arm64': 4.61.1 + '@rollup/rollup-win32-arm64-msvc': 4.61.1 + '@rollup/rollup-win32-ia32-msvc': 4.61.1 + '@rollup/rollup-win32-x64-gnu': 4.61.1 + '@rollup/rollup-win32-x64-msvc': 4.61.1 fsevents: 2.3.3 router@2.2.0: @@ -6448,7 +6445,7 @@ snapshots: sass@1.97.3: dependencies: chokidar: 4.0.3 - immutable: 5.1.5 + immutable: 5.1.6 source-map-js: 1.2.1 optionalDependencies: '@parcel/watcher': 2.5.6 @@ -6463,7 +6460,7 @@ snapshots: semver@7.7.4: {} - semver@7.8.1: {} + semver@7.8.4: {} send@1.2.1: dependencies: @@ -6518,7 +6515,7 @@ snapshots: object-inspect: 1.13.4 side-channel-map: 1.0.1 - side-channel@1.1.0: + side-channel@1.1.1: dependencies: es-errors: 1.3.0 object-inspect: 1.13.4 @@ -6672,7 +6669,7 @@ snapshots: symbol-tree@3.2.4: {} - tar@7.5.15: + tar@7.5.16: dependencies: '@isaacs/fs-minipass': 4.0.1 chownr: 3.0.0 @@ -6682,25 +6679,25 @@ snapshots: tinybench@2.9.0: {} - tinyexec@1.2.2: {} + tinyexec@1.2.4: {} tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 - tinyglobby@0.2.16: + tinyglobby@0.2.17: dependencies: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 tinyrainbow@3.1.0: {} - tldts-core@7.4.0: {} + tldts-core@7.4.2: {} - tldts@7.4.0: + tldts@7.4.2: dependencies: - tldts-core: 7.4.0 + tldts-core: 7.4.2 to-regex-range@5.0.1: dependencies: @@ -6710,7 +6707,7 @@ snapshots: tough-cookie@6.0.1: dependencies: - tldts: 7.4.0 + tldts: 7.4.2 tr46@6.0.0: dependencies: @@ -6775,43 +6772,43 @@ snapshots: vary@1.1.2: {} - vite@7.3.2(@types/node@25.9.1)(sass@1.97.3): + vite@7.3.2(@types/node@25.9.3)(sass@1.97.3): dependencies: esbuild: 0.27.3 fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 postcss: 8.5.15 - rollup: 4.60.4 + rollup: 4.61.1 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 fsevents: 2.3.3 sass: 1.97.3 - vitest@4.1.7(@types/node@25.9.1)(jsdom@27.4.0)(vite@7.3.2(@types/node@25.9.1)(sass@1.97.3)): + vitest@4.1.8(@types/node@25.9.3)(jsdom@27.4.0)(vite@7.3.2(@types/node@25.9.3)(sass@1.97.3)): dependencies: - '@vitest/expect': 4.1.7 - '@vitest/mocker': 4.1.7(vite@7.3.2(@types/node@25.9.1)(sass@1.97.3)) - '@vitest/pretty-format': 4.1.7 - '@vitest/runner': 4.1.7 - '@vitest/snapshot': 4.1.7 - '@vitest/spy': 4.1.7 - '@vitest/utils': 4.1.7 + '@vitest/expect': 4.1.8 + '@vitest/mocker': 4.1.8(vite@7.3.2(@types/node@25.9.3)(sass@1.97.3)) + '@vitest/pretty-format': 4.1.8 + '@vitest/runner': 4.1.8 + '@vitest/snapshot': 4.1.8 + '@vitest/spy': 4.1.8 + '@vitest/utils': 4.1.8 es-module-lexer: 2.1.0 expect-type: 1.3.0 magic-string: 0.30.21 - obug: 2.1.1 + obug: 2.1.2 pathe: 2.0.3 picomatch: 4.0.4 std-env: 4.1.0 tinybench: 2.9.0 - tinyexec: 1.2.2 - tinyglobby: 0.2.16 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vite: 7.3.2(@types/node@25.9.1)(sass@1.97.3) + vite: 7.3.2(@types/node@25.9.3)(sass@1.97.3) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 jsdom: 27.4.0 transitivePeerDependencies: - msw diff --git a/ui/src/app/app.html b/ui/src/app/app.html index 2b7f01c..c959366 100644 --- a/ui/src/app/app.html +++ b/ui/src/app/app.html @@ -717,21 +717,31 @@