diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..755696f --- /dev/null +++ b/.dockerignore @@ -0,0 +1,17 @@ +.git +.github +.gitea +.idea +.claude +.npm-cache +node_modules +build +.svelte-kit +.env +.env.* +!.env.example +*.zip +npm-debug.log* +pnpm-debug.log* +Dockerfile +docker-compose.yml diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..f136dd3 --- /dev/null +++ b/.env.example @@ -0,0 +1,13 @@ +PUBLIC_SITE_URL=https://trade.flamy.studio +PUBLIC_SITE_NAME=Flamy Trade +PUBLIC_SITE_DESCRIPTION=Публичная витрина ML-прогнозов для крипторынка. + +HOST=0.0.0.0 +PORT=3000 +ORIGIN=https://trade.flamy.studio +BODY_SIZE_LIMIT=1M +SHUTDOWN_TIMEOUT=15 + +APP_HOST_IP=10.20.0.20 +APP_PUBLISHED_PORT=18082 +APP_IMAGE_TAG=local diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1eccb3e --- /dev/null +++ b/.gitattributes @@ -0,0 +1,9 @@ +* text=auto eol=lf +*.svelte text eol=lf +*.ts text eol=lf +*.js text eol=lf +*.json text eol=lf +*.yaml text eol=lf +*.yml text eol=lf +*.md text eol=lf +*.css text eol=lf diff --git a/.gitignore b/.gitignore index 2550932..4b9fea0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ node_modules +.npm-cache +.corepack # Output .output @@ -24,4 +26,4 @@ vite.config.ts.timestamp-* #IDE & AI .claude -.idea \ No newline at end of file +.idea diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7db4a54 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,52 @@ +# syntax=docker/dockerfile:1.7 + +ARG NODE_IMAGE=node:24.18.0-alpine@sha256:a0b9bf06e4e6193cf7a0f58816cc935ff8c2a908f81e6f1a95432d679c54fbfd + +FROM ${NODE_IMAGE} AS base +WORKDIR /app +ENV PNPM_HOME=/pnpm +ENV PATH=${PNPM_HOME}:${PATH} +RUN corepack enable + +FROM base AS deps +COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./ +RUN pnpm install --frozen-lockfile + +FROM deps AS quality +COPY . . +RUN pnpm format:check +RUN pnpm lint +RUN pnpm check + +FROM quality AS build +RUN pnpm build + +FROM base AS prod-deps +COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./ +RUN pnpm install --frozen-lockfile --prod --ignore-scripts + +FROM ${NODE_IMAGE} AS runtime +WORKDIR /app + +ARG BUILD_DATE +ARG VCS_REF + +LABEL org.opencontainers.image.title="Flamy Trade" +LABEL org.opencontainers.image.description="SvelteKit frontend for trade.flamy.studio" +LABEL org.opencontainers.image.created="${BUILD_DATE}" +LABEL org.opencontainers.image.revision="${VCS_REF}" + +ENV NODE_ENV=production +ENV HOST=0.0.0.0 +ENV PORT=3000 +ENV ORIGIN=https://trade.flamy.studio +ENV BODY_SIZE_LIMIT=1M +ENV SHUTDOWN_TIMEOUT=15 + +COPY --from=prod-deps --chown=node:node /app/node_modules ./node_modules +COPY --from=build --chown=node:node /app/build ./build +COPY --from=build --chown=node:node /app/package.json ./package.json + +USER node +EXPOSE 3000 +CMD ["node", "build/index.js"] diff --git a/README.md b/README.md index 65a1552..9791c35 100644 --- a/README.md +++ b/README.md @@ -1,316 +1,133 @@ -# Flamy Trade — Frontend +# Flamy Trade -Публичный лендинг и дашборд ML-прогнозов для крипторынка. Построен на **SvelteKit 5** (Runes API), **Tailwind v4**, **TypeScript** и **lightweight-charts v5**. +Публичный frontend для `trade.flamy.studio`: лендинг, блог и демонстрационный дашборд ML-прогнозов по крипторынку. ---- +Проект построен на SvelteKit, Svelte 5 Runes, Tailwind CSS v4, TypeScript и `lightweight-charts`. -## Стек +## Требования -| Слой | Технология | -|---|---| -| Фреймворк | SvelteKit 5 (runes, SSR) | -| Язык | TypeScript (strict) | -| Стили | Tailwind CSS v4 (Vite plugin, `@theme`) | -| Графики | lightweight-charts v5 (TradingView) | -| Сервер | `@sveltejs/adapter-node` (Node.js) | -| Пакетный менеджер | pnpm | +```text +Node.js: >=24.0.0 <25 +pnpm: >=11.15.1 <12 +``` ---- +В Windows PowerShell запускайте pnpm через `pnpm.cmd`, если выполнение `.ps1`-скриптов отключено. ## Быстрый старт -**Требования:** Node.js ≥ 20, pnpm ≥ 9 - ```bash -# 1. Установить зависимости pnpm install - -# 2. Запустить dev-сервер pnpm dev - -# 3. Открыть в браузере -# http://localhost:5173 ``` -Остальные команды: +Локальный адрес по умолчанию: + +```text +http://localhost:5173 +``` + +## Команды ```bash -pnpm build # Сборка для продакшена (папка build/) -pnpm preview # Превью продакшен-сборки -pnpm check # Svelte + TypeScript проверка типов -pnpm lint # ESLint + Prettier проверка -pnpm format # Автоформатирование +pnpm format # автоформатирование +pnpm format:check # проверка форматирования +pnpm lint # ESLint +pnpm check # Svelte + TypeScript +pnpm build # production build +pnpm preview # preview production build +pnpm audit # аудит зависимостей ``` ---- - -## Структура проекта - -``` -src/ -├── lib/ -│ ├── components/ -│ │ ├── Chart.svelte # lightweight-charts обёртка -│ │ ├── home/ -│ │ │ ├── DashboardMockup.svelte # 3D-макет на главной -│ │ │ └── DashboardStatus.svelte -│ │ ├── layout/ -│ │ │ ├── Header.svelte # Фиксированная шапка + мобильное меню -│ │ │ └── Footer.svelte -│ │ └── ui/ -│ │ ├── Button.svelte # Универсальная кнопка/ссылка -│ │ └── Logo.svelte -│ ├── blog/ -│ │ └── posts.ts # Статьи блога (статические данные) -│ ├── stores/ -│ │ └── chartStore.ts # Типы + генератор фейковых данных -│ ├── utils.ts # cn() — утилита для className -│ └── index.ts -│ -├── routes/ -│ ├── +layout.svelte # Корневой layout: Header, Footer, шрифты -│ ├── +page.svelte # Главная страница (секции) -│ ├── +error.svelte # Страница ошибки -│ ├── (sections)/ # Секции главной страницы -│ │ ├── Hero.svelte -│ │ ├── Ticker.svelte -│ │ ├── About.svelte -│ │ ├── Features.svelte -│ │ ├── Stats.svelte -│ │ ├── BlogPreview.svelte -│ │ └── Cta.svelte -│ ├── about/ -│ │ ├── +page.svelte -│ │ └── _data.ts -│ ├── blog/ -│ │ ├── +page.svelte # Список статей -│ │ └── [slug]/ -│ │ ├── +page.ts # Загрузка статьи по slug -│ │ └── +page.svelte # Статья -│ └── dashboard/ -│ └── +page.svelte # Интерактивный дашборд с графиком -│ -└── routes/layout.css # Tailwind @theme + глобальные стили -``` - ---- - -## Дизайн-система - -### Цвета (`layout.css`) - -```css ---color-primary: #fe4b07 /* Акцент — оранжевый */ ---color-primary-h:#c83e06 /* Hover-состояние */ ---color-bg: #09080a /* Фон страницы */ ---color-bg-e: #0f0e10 /* Elevated (шапка, карточки) */ ---color-bg-c: #141318 /* Card background */ ---color-bg-h: #1a191e /* Hover / бордеры */ ---color-title: #f0ede6 /* Основной текст */ ---color-desc: #8a887f /* Вторичный текст */ -``` - -В Tailwind используются как `bg-primary`, `text-desc`, `border-bg-h` и т.д. - -### Шрифты - -| Переменная | Семейство | Применение | -|---|---|---| -| `font-display` | Unbounded | Заголовки, кнопки, тикеры | -| `font-sans` | DM Sans | Основной текст | -| `font-mono` | JetBrains Mono | Цены, метки, метаданные | - -Подключаются через Google Fonts в `+layout.svelte`. - -### Компонент `Button.svelte` - -```svelte - - - - - -``` - -Props: `href?`, `target?`, `variant?: 'primary' | 'secondary'`, `class?` - ---- - -## Дашборд и Charts - -### Архитектура данных - -``` -chartStore.ts → generateChartData(symbolId, timeframeId) - └── возвращает ChartData - ├── candles: CandleBar[] // 160 свечей - ├── prediction: PredPoint[] // 19 прогнозных точек - ├── signal: Signal // direction, confidence, entry/tp/sl - ├── currentPrice: number - └── change24h(Pct): number -``` - -`generateChartData` — **заглушка с детерминированными фейковыми данными**. При подключении реального бекенда её нужно заменить на API-запрос, сохранив возвращаемые типы: - -```typescript -// chartStore.ts — заменить эту функцию на реальный запрос: -export async function fetchChartData(symbolId: string, tfId: TimeframeId): Promise { - const res = await fetch(`/api/chart/${symbolId}?tf=${tfId}`); - return res.json(); -} -``` - -### Компонент `Chart.svelte` - -```svelte - -``` - -| Prop | Тип | Описание | -|---|---|---| -| `data` | `ChartData` | Свечи + прогноз + сигнал | -| `decimals` | `number` | Кол-во знаков после запятой для цены | -| `height` | `number` | Высота canvas в пикселях (default: 520) | - -Что рендерится: -- **CandlestickSeries** — исторические зелёные/красные свечи -- **LineSeries** — пунктирная оранжевая линия ML-прогноза (19 свечей вперёд) -- **PriceLine** × 3 — горизонтальные линии Entry / TP / SL с подписями на шкале -- **OHLC тултип** — кастомный HTML-оверлей при наведении (показывает O/H/L/C и ML-значение) -- **ResizeObserver** — автоматически подстраивает ширину и высоту при изменении окна - -### Таймфреймы и символы - -Определены в `chartStore.ts`: - -```typescript -SYMBOLS // 8 монет: BTC ETH SOL BNB XRP ADA DOGE LINK -TIMEFRAMES // 6 таймфреймов: 1m 5m 15m 1h 4h 1d -``` - ---- - -## Контракт API (для бекенда) - -Дашборд ожидает от бекенда следующую форму ответа: - -```typescript -type ChartData = { - candles: Array<{ - time: number; // Unix timestamp (UTC seconds) - open: number; - high: number; - low: number; - close: number; - }>; - prediction: Array<{ - time: number; // Unix timestamp будущих свечей - value: number; // Прогнозная цена (mid/close) - }>; - signal: { - direction: 'long' | 'short'; - confidence: number; // 0–100 - entry: number; - tp: number; - sl: number; - }; - currentPrice: number; - change24h: number; - change24hPct: number; -}; -``` - -Эндпоинт (предполагаемый): -``` -GET /api/chart/:symbol?tf=5m -``` - ---- - -## Блог - -Статьи хранятся в `src/lib/blog/posts.ts` как статический массив `Post[]`. - -```typescript -type Post = { - id: number; - slug: string; // URL: /blog/:slug - date: string; // ISO 8601 - title: string; - description: string; - tags: string[]; - content: string; // HTML-строка -}; -``` - -Для подключения CMS — заменить `posts` на API-запрос в `+page.ts` / `+page.server.ts`. - ---- +`pnpm outdated` может показывать `@types/node` 26.x и TypeScript 7.x. Это не ошибка текущего стека: проект закреплён на Node 24 LTS, а `@sveltejs/kit` и `typescript-eslint` на текущих версиях требуют TypeScript `<6.1`. ## Конфигурация -### SvelteKit (`svelte.config.js`) +Основные изменяемые значения вынесены в `.env.example`. -- Адаптер: `adapter-node` (деплой как Node.js-сервер) -- Runes: принудительно включены для всех файлов вне `node_modules` - -### Tailwind v4 (`layout.css`) - -Tailwind подключается через Vite-плагин (`@tailwindcss/vite`), конфиг CSS-первый — все кастомные токены в блоке `@theme` в `src/routes/layout.css`. - -**Добавить новый токен:** -```css -/* layout.css */ -@theme { - --color-accent: #your-color; -} -``` -После этого доступен как `bg-accent`, `text-accent` и т.д. - ---- - -## Деплой - -Сборка производит Node.js-сервер: +Публичные значения сайта: ```bash -pnpm build -node build/index.js +PUBLIC_SITE_URL=https://trade.flamy.studio +PUBLIC_SITE_NAME=Flamy Trade +PUBLIC_SITE_DESCRIPTION=Публичная витрина ML-прогнозов для крипторынка. ``` -Переменные окружения: -``` -PORT=3000 # порт (default: 3000) -HOST=0.0.0.0 # хост -ORIGIN=https://... # обязательно при deploy за проксей +Runtime-переменные SvelteKit adapter-node: + +```bash +HOST=0.0.0.0 +PORT=3000 +ORIGIN=https://trade.flamy.studio +BODY_SIZE_LIMIT=1M +SHUTDOWN_TIMEOUT=15 ``` -Docker (минимальный `Dockerfile`): -```dockerfile -FROM node:22-alpine -WORKDIR /app -COPY build/ ./build/ -COPY package.json . -RUN npm install --omit=dev --ignore-scripts -CMD ["node", "build/index.js"] +Docker Compose: + +```bash +APP_HOST_IP=10.20.0.20 +APP_PUBLISHED_PORT=18082 +APP_IMAGE_TAG= ``` ---- +## Структура -## Соглашения по коду +```text +src/lib/blog/posts.ts # статические статьи блога +src/lib/config/site.ts # единая конфигурация сайта и canonical URL +src/lib/stores/chartStore.ts # типы графика и демонстрационный provider +src/lib/components/Chart.svelte # lightweight-charts компонент +src/routes/healthz/+server.ts # health endpoint +src/routes/sitemap.xml/+server.ts # sitemap +docker/nginx/default.conf # project nginx +docs/deployment.md # runbook развёртывания +``` -- **Svelte 5 Runes** везде: `$state`, `$derived`, `$effect`, `$props` — никакого legacy API -- **Нет `export let`** — только деструктуризация `$props()` -- **Tailwind-first** — inline-стили только там, где Tailwind не справляется (динамические значения, chart dimensions) -- **cn()** из `$lib/utils` для условного объединения классов -- **Нет комментариев** если смысл очевиден из имён; комментарий — только для неочевидного инварианта -- **SSR-safe** — всё что требует `window`/`document` — только в `onMount` -- **Cleanup** — каждый `onMount` возвращает функцию очистки (removeEventListener, disconnect, remove) +## Данные дашборда ---- +Текущий provider в `chartStore.ts` генерирует демонстрационные данные. Он не является реальным торговым API и не меняет контракт будущего backend. -## Известные ограничения +Ожидаемая форма `ChartData`: -- Данные в дашборде — **фейковые** (детерминированный генератор). Требует подключения реального API бекенда через замену `generateChartData` в `chartStore.ts` -- Прогнозная линия — условная визуализация; реальная модель возвращает `prediction[]` из бекенда -- Блог — статические данные в коде; для production рекомендуется CMS или headless API +```typescript +type ChartData = { + candles: Array<{ time: number; open: number; high: number; low: number; close: number }>; + prediction: Array<{ time: number; value: number }>; + signal: { + direction: 'long' | 'short'; + confidence: number; + entry: number; + tp: number; + sl: number; + }; + currentPrice: number; + change24h: number; + change24hPct: number; +}; +``` + +## Блог + +Статьи хранятся как типизированные блоки, а не как HTML-строки. Это позволяет рендерить контент без `{@html}` и без отдельной санитаризации. + +## Production + +Production-сборка рассчитана на схему: + +```text +Internet -> Caddy -> 10.20.0.20:18082 -> nginx -> app:3000 +``` + +Подробный порядок развёртывания, Caddy block, smoke-check и rollback описаны в [docs/deployment.md](docs/deployment.md). + +## Что не входит в текущий этап + +Пока не подключаются: + +- ML-runtime; +- реальный API; +- S3; +- база данных; +- Redis; +- Telegram egress; +- публикация ML API через Caddy. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..5fe69b0 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,100 @@ +services: + app: + build: + context: . + dockerfile: Dockerfile + args: + BUILD_DATE: ${BUILD_DATE:-} + VCS_REF: ${VCS_REF:-} + image: flamy-trade:${APP_IMAGE_TAG:-local} + restart: unless-stopped + init: true + read_only: true + environment: + NODE_ENV: production + HOST: 0.0.0.0 + PORT: 3000 + ORIGIN: ${ORIGIN:-https://trade.flamy.studio} + BODY_SIZE_LIMIT: ${BODY_SIZE_LIMIT:-1M} + SHUTDOWN_TIMEOUT: ${SHUTDOWN_TIMEOUT:-15} + PUBLIC_SITE_URL: ${PUBLIC_SITE_URL:-https://trade.flamy.studio} + PUBLIC_SITE_NAME: ${PUBLIC_SITE_NAME:-Flamy Trade} + PUBLIC_SITE_DESCRIPTION: ${PUBLIC_SITE_DESCRIPTION:-Публичная витрина ML-прогнозов для крипторынка.} + expose: + - '3000' + networks: + - backend + cpus: 0.50 + mem_limit: 384m + mem_reservation: 128m + memswap_limit: 384m + pids_limit: 128 + security_opt: + - no-new-privileges:true + cap_drop: + - ALL + tmpfs: + - /tmp:size=32m,noexec,nosuid,nodev + healthcheck: + test: + [ + 'CMD-SHELL', + 'node -e "fetch(''http://127.0.0.1:3000/healthz'').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"' + ] + interval: 30s + timeout: 5s + retries: 3 + start_period: 20s + logging: + driver: json-file + options: + max-size: 10m + max-file: '3' + + nginx: + image: nginx:1.30.4-alpine@sha256:97d490c12ba55b4946b01546d1c3ed324e8d41ab1c9fcb2a616aa470620e5b46 + restart: unless-stopped + init: true + read_only: true + depends_on: + app: + condition: service_healthy + ports: + - name: http + target: 8080 + published: '${APP_PUBLISHED_PORT:-18082}' + host_ip: '${APP_HOST_IP:-10.20.0.20}' + protocol: tcp + app_protocol: http + volumes: + - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro + networks: + - backend + cpus: 0.10 + mem_limit: 64m + mem_reservation: 16m + memswap_limit: 64m + pids_limit: 64 + security_opt: + - no-new-privileges:true + cap_drop: + - ALL + tmpfs: + - /var/cache/nginx:size=32m,nosuid,nodev + - /var/run:size=8m,nosuid,nodev + - /tmp:size=16m,noexec,nosuid,nodev + healthcheck: + test: ['CMD-SHELL', 'wget -qO- http://127.0.0.1:8080/healthz >/dev/null || exit 1'] + interval: 30s + timeout: 5s + retries: 3 + start_period: 20s + logging: + driver: json-file + options: + max-size: 10m + max-file: '3' + +networks: + backend: + internal: true diff --git a/docker/nginx/default.conf b/docker/nginx/default.conf new file mode 100644 index 0000000..e194ddb --- /dev/null +++ b/docker/nginx/default.conf @@ -0,0 +1,51 @@ +map $http_x_forwarded_proto $forwarded_proto { + default $http_x_forwarded_proto; + "" $scheme; +} + +server { + listen 8080; + server_name _; + + client_max_body_size 1m; + + add_header X-Content-Type-Options "nosniff" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()" always; + add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self'" always; + + location /_app/immutable/ { + proxy_pass http://app:3000; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Proto $forwarded_proto; + add_header Cache-Control "public, max-age=31536000, immutable" always; + } + + location ~* \.(?:css|js|mjs|svg|png|jpg|jpeg|gif|webp|ico|ttf|woff2?)$ { + proxy_pass http://app:3000; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Proto $forwarded_proto; + add_header Cache-Control "public, max-age=86400" always; + } + + location / { + proxy_pass http://app:3000; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Proto $forwarded_proto; + proxy_set_header Connection ""; + add_header Cache-Control "no-store" always; + } +} diff --git a/docs/deployment.md b/docs/deployment.md new file mode 100644 index 0000000..9ca54ac --- /dev/null +++ b/docs/deployment.md @@ -0,0 +1,134 @@ +# Развёртывание Flamy Trade + +Документ описывает production-развёртывание сайта `trade.flamy.studio` без ML-runtime и без будущего API. Эти части подключаются отдельно. + +## Схема + +```text +Internet + -> Router :80/:443 + -> edge-proxy VM / Caddy + -> 10.20.0.20:18082 + -> flamy_trade_nginx + -> flamy_trade_app:3000 +``` + +На VM публикуется только nginx. Node-приложение доступно только во внутренней Docker-сети. + +## Переменные + +Скопируйте `.env.example` в `.env` на сервере и проверьте значения: + +```bash +PUBLIC_SITE_URL=https://trade.flamy.studio +PUBLIC_SITE_NAME=Flamy Trade +PUBLIC_SITE_DESCRIPTION=Публичная витрина ML-прогнозов для крипторынка. + +HOST=0.0.0.0 +PORT=3000 +ORIGIN=https://trade.flamy.studio +BODY_SIZE_LIMIT=1M +SHUTDOWN_TIMEOUT=15 + +APP_HOST_IP=10.20.0.20 +APP_PUBLISHED_PORT=18082 +APP_IMAGE_TAG= +``` + +Перед фиксацией порта проверьте, что `18082` свободен: + +```bash +sudo ss -lntup | grep ':18082' +docker ps --format 'table {{.Names}}\t{{.Ports}}' +``` + +## Сборка + +```bash +pnpm install --frozen-lockfile +pnpm format:check +pnpm lint +pnpm check +pnpm build +pnpm audit +``` + +`pnpm outdated` должен проверяться вручную. На текущем стеке допустимы только осознанные удержания: `@types/node` на ветке 24 под Node 24 LTS и TypeScript 6.x до обновления peer constraints в SvelteKit/typescript-eslint. + +Docker: + +```bash +docker compose config +docker compose build --pull +docker compose up -d --wait +docker compose ps +docker compose logs --tail=200 +``` + +## Caddy + +Блок для edge-proxy: + +```caddyfile +trade.flamy.studio { + encode zstd gzip + + reverse_proxy 10.20.0.20:18082 { + header_up Host {host} + header_up X-Real-IP {remote_host} + } +} +``` + +Перед reload: + +```bash +sudo cp -a /etc/caddy/Caddyfile /etc/caddy/Caddyfile.bak.$(date +%F_%H%M%S) +sudo caddy validate --config /etc/caddy/Caddyfile +sudo systemctl reload caddy +``` + +## Smoke-check + +С docker-runtime: + +```bash +curl -fsS http://10.20.0.20:18082/healthz +curl -I http://10.20.0.20:18082/ +``` + +Снаружи: + +```bash +curl -I http://trade.flamy.studio +curl -I https://trade.flamy.studio +curl -fsS https://trade.flamy.studio/healthz +``` + +Маршруты: + +```text +/ 200 +/about 200 +/blog 200 +/blog/osnovy-upravleniya-riskami 200 +/dashboard 200 +/healthz 200 +/favicon.svg 200 +/robots.txt 200 +/sitemap.xml 200 +/nesuschestvuyuschiy-url 404 +``` + +## Rollback + +1. Каждый image получает тег git SHA через `APP_IMAGE_TAG`. +2. Предыдущий image не удаляется до успешного smoke-check. +3. Для отката поменяйте `APP_IMAGE_TAG` на предыдущий SHA. +4. Выполните: + +```bash +docker compose up -d --no-build +``` + +Если проблема в маршрутизации, восстановите backup Caddyfile и выполните `sudo systemctl reload caddy`. diff --git a/package.json b/package.json index 12d7bf0..e2afaf5 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,11 @@ "private": true, "version": "0.0.1", "type": "module", + "packageManager": "pnpm@11.15.1", + "engines": { + "node": ">=24.0.0 <25", + "pnpm": ">=11.15.1 <12" + }, "scripts": { "dev": "vite dev", "build": "vite build", @@ -10,35 +15,36 @@ "prepare": "svelte-kit sync || echo ''", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", - "lint": "prettier --check . && eslint .", + "format:check": "prettier --check .", + "lint": "eslint .", "format": "prettier --write ." }, "devDependencies": { - "@eslint/compat": "^2.0.4", - "@eslint/js": "^10.0.1", - "@sveltejs/adapter-node": "^5.5.4", - "@sveltejs/kit": "^2.57.0", - "@sveltejs/vite-plugin-svelte": "^7.0.0", - "@tailwindcss/vite": "^4.2.2", - "@types/node": "^24", - "eslint": "^10.2.0", - "eslint-config-prettier": "^10.1.8", - "eslint-plugin-svelte": "^3.17.0", - "globals": "^17.4.0", - "prettier": "^3.8.1", - "prettier-plugin-svelte": "^3.5.1", - "prettier-plugin-tailwindcss": "^0.7.2", - "svelte": "^5.55.2", - "svelte-check": "^4.4.6", - "tailwindcss": "^4.2.2", - "typescript": "^6.0.2", - "typescript-eslint": "^8.58.1", - "vite": "^8.0.7" + "@eslint/compat": "2.1.0", + "@eslint/js": "10.0.1", + "@sveltejs/adapter-node": "5.5.7", + "@sveltejs/vite-plugin-svelte": "7.2.0", + "@tailwindcss/vite": "4.3.3", + "@types/node": "24.12.4", + "eslint": "10.7.0", + "eslint-config-prettier": "10.1.8", + "eslint-plugin-svelte": "3.21.0", + "globals": "17.7.0", + "prettier": "3.9.5", + "prettier-plugin-svelte": "4.1.1", + "prettier-plugin-tailwindcss": "0.8.1", + "svelte": "5.56.6", + "svelte-check": "4.7.3", + "tailwindcss": "4.3.3", + "typescript": "6.0.3", + "typescript-eslint": "8.64.0", + "vite": "8.1.5" }, "dependencies": { - "clsx": "^2.1.1", - "gsap": "^3.15.0", - "lightweight-charts": "^5.2.0", - "tailwind-merge": "^3.6.0" + "@sveltejs/kit": "2.70.1", + "clsx": "2.1.1", + "gsap": "3.15.0", + "lightweight-charts": "5.2.0", + "tailwind-merge": "3.6.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c5e0f1a..1bf881d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,94 +4,97 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + cookie: 0.7.2 + importers: .: dependencies: + '@sveltejs/kit': + specifier: 2.70.1 + version: 2.70.1(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.6(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)))(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3)(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)) clsx: - specifier: ^2.1.1 + specifier: 2.1.1 version: 2.1.1 gsap: - specifier: ^3.15.0 + specifier: 3.15.0 version: 3.15.0 lightweight-charts: - specifier: ^5.2.0 + specifier: 5.2.0 version: 5.2.0 tailwind-merge: - specifier: ^3.6.0 + specifier: 3.6.0 version: 3.6.0 devDependencies: '@eslint/compat': - specifier: ^2.0.4 - version: 2.1.0(eslint@10.4.0(jiti@2.7.0)) + specifier: 2.1.0 + version: 2.1.0(eslint@10.7.0(jiti@2.7.0)) '@eslint/js': - specifier: ^10.0.1 - version: 10.0.1(eslint@10.4.0(jiti@2.7.0)) + specifier: 10.0.1 + version: 10.0.1(eslint@10.7.0(jiti@2.7.0)) '@sveltejs/adapter-node': - specifier: ^5.5.4 - version: 5.5.4(@sveltejs/kit@2.60.1(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(jiti@2.7.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(jiti@2.7.0))) - '@sveltejs/kit': - specifier: ^2.57.0 - version: 2.60.1(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(jiti@2.7.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(jiti@2.7.0)) + specifier: 5.5.7 + version: 5.5.7(@sveltejs/kit@2.70.1(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.6(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)))(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3)(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0))) '@sveltejs/vite-plugin-svelte': - specifier: ^7.0.0 - version: 7.1.2(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(jiti@2.7.0)) + specifier: 7.2.0 + version: 7.2.0(svelte@5.56.6(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)) '@tailwindcss/vite': - specifier: ^4.2.2 - version: 4.3.0(vite@8.0.13(@types/node@24.12.4)(jiti@2.7.0)) + specifier: 4.3.3 + version: 4.3.3(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)) '@types/node': - specifier: ^24 + specifier: 24.12.4 version: 24.12.4 eslint: - specifier: ^10.2.0 - version: 10.4.0(jiti@2.7.0) + specifier: 10.7.0 + version: 10.7.0(jiti@2.7.0) eslint-config-prettier: - specifier: ^10.1.8 - version: 10.1.8(eslint@10.4.0(jiti@2.7.0)) + specifier: 10.1.8 + version: 10.1.8(eslint@10.7.0(jiti@2.7.0)) eslint-plugin-svelte: - specifier: ^3.17.0 - version: 3.17.1(eslint@10.4.0(jiti@2.7.0))(svelte@5.55.9(@typescript-eslint/types@8.59.4)) + specifier: 3.21.0 + version: 3.21.0(eslint@10.7.0(jiti@2.7.0))(svelte@5.56.6(@typescript-eslint/types@8.64.0)) globals: - specifier: ^17.4.0 - version: 17.6.0 + specifier: 17.7.0 + version: 17.7.0 prettier: - specifier: ^3.8.1 - version: 3.8.3 + specifier: 3.9.5 + version: 3.9.5 prettier-plugin-svelte: - specifier: ^3.5.1 - version: 3.5.2(prettier@3.8.3)(svelte@5.55.9(@typescript-eslint/types@8.59.4)) + specifier: 4.1.1 + version: 4.1.1(prettier@3.9.5)(svelte@5.56.6(@typescript-eslint/types@8.64.0)) prettier-plugin-tailwindcss: - specifier: ^0.7.2 - version: 0.7.4(prettier-plugin-svelte@3.5.2(prettier@3.8.3)(svelte@5.55.9(@typescript-eslint/types@8.59.4)))(prettier@3.8.3) + specifier: 0.8.1 + version: 0.8.1(prettier-plugin-svelte@4.1.1(prettier@3.9.5)(svelte@5.56.6(@typescript-eslint/types@8.64.0)))(prettier@3.9.5) svelte: - specifier: ^5.55.2 - version: 5.55.9(@typescript-eslint/types@8.59.4) + specifier: 5.56.6 + version: 5.56.6(@typescript-eslint/types@8.64.0) svelte-check: - specifier: ^4.4.6 - version: 4.4.8(picomatch@4.0.4)(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@6.0.3) + specifier: 4.7.3 + version: 4.7.3(picomatch@4.0.4)(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3) tailwindcss: - specifier: ^4.2.2 - version: 4.3.0 + specifier: 4.3.3 + version: 4.3.3 typescript: - specifier: ^6.0.2 + specifier: 6.0.3 version: 6.0.3 typescript-eslint: - specifier: ^8.58.1 - version: 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) + specifier: 8.64.0 + version: 8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3) vite: - specifier: ^8.0.7 - version: 8.0.13(@types/node@24.12.4)(jiti@2.7.0) + specifier: 8.1.5 + version: 8.1.5(@types/node@24.12.4)(jiti@2.7.0) packages: - '@emnapi/core@1.10.0': - resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + '@emnapi/core@1.11.1': + resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} - '@emnapi/runtime@1.10.0': - resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + '@emnapi/runtime@1.11.1': + resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} - '@emnapi/wasi-threads@1.2.1': - resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + '@emnapi/wasi-threads@1.2.2': + resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} '@eslint-community/eslint-utils@4.9.1': resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} @@ -137,8 +140,8 @@ packages: resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/plugin-kit@0.7.1': - resolution: {integrity: sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==} + '@eslint/plugin-kit@0.7.2': + resolution: {integrity: sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@humanfs/core@0.19.2': @@ -177,103 +180,109 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@napi-rs/wasm-runtime@1.1.4': - resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} + '@napi-rs/wasm-runtime@1.1.6': + resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} peerDependencies: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 - '@oxc-project/types@0.130.0': - resolution: {integrity: sha512-ibD2usx9JRu7f5pu2tMKMI4cpA4NgXJQoYRP4pQ7Pxmn1l6k/53qWtQWZayhYy3X4QZkt90Ot+mJEaeXouio6Q==} + '@oxc-project/types@0.139.0': + resolution: {integrity: sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==} '@polka/url@1.0.0-next.29': resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} - '@rolldown/binding-android-arm64@1.0.1': - resolution: {integrity: sha512-fJI3I0r3C3Oj/zdBCpaCmBRZYf07xpaq4yCfDDoSFm+beWNzbIl26puW8RraUdugoJw/95zerNOn6jasAhzSmg==} + '@rolldown/binding-android-arm64@1.1.5': + resolution: {integrity: sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.1': - resolution: {integrity: sha512-cKnAhWEsV7TPcA/5EAteDp6KcJZBQ2G+BqE7zayMMi7kMvwRsbv7WT9aOnn0WNl4SKEIf43vjS31iUPu80nzXg==} + '@rolldown/binding-darwin-arm64@1.1.5': + resolution: {integrity: sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.1': - resolution: {integrity: sha512-YKrVwQjIRBPo+5G/u03wGjbdy4q7pyzCe93DK9VJ7zkVmeg8LJ7GbgsiHWdR4xSoe4CAXRD7Bcjgbtr64bkXNg==} + '@rolldown/binding-darwin-x64@1.1.5': + resolution: {integrity: sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.1': - resolution: {integrity: sha512-z/oBsREo46SsFqBwYtFe0kpJeBijAT48O/WXLI4suiCLBkr03RTtTJMCzSdDd2znlh8VJizL09XVkQgk8IZonw==} + '@rolldown/binding-freebsd-x64@1.1.5': + resolution: {integrity: sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.1': - resolution: {integrity: sha512-ik8q7GM11zxvYxFc2PeDcT6TBvhCQMaUxfph/M5l9sKuTs/Sjg3L+Byw0F7w0ZVLBZmx30P+gG0ECzzN+MFcmQ==} + '@rolldown/binding-linux-arm-gnueabihf@1.1.5': + resolution: {integrity: sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.1': - resolution: {integrity: sha512-QoSx2EkyrrdZ6kcyE8stqZ62t0Yra8Fs5ia9lOxJrh6TMQJK7gQKmscdTHf7pOXKREKrVwOtJcQG3qVSfc866A==} + '@rolldown/binding-linux-arm64-gnu@1.1.5': + resolution: {integrity: sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.0.1': - resolution: {integrity: sha512-uwNwFpwKeNiZawfAWBgg0VIztPTV3ihhh1vV334h9ivnNLorxnQMU6Fz8wG1Zb4Qh9LC1/MkcyT3YlDXG3Rsgg==} + '@rolldown/binding-linux-arm64-musl@1.1.5': + resolution: {integrity: sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.0.1': - resolution: {integrity: sha512-zY1bul7OWr7DFBiJ++wofXvnr8B45ce3QsQUhKrIhXsygAh7bTkwyeM1bi1a2g5C/yC/N8TZyGDEoMfm/l9mpg==} + '@rolldown/binding-linux-ppc64-gnu@1.1.5': + resolution: {integrity: sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] + libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.0.1': - resolution: {integrity: sha512-0frlsT/f4Ft6I7SMESTKnF3cZsdicQn1dCMkF/jT9wDLE+gGoiQfv1nmT9e+s7s/fekvvy6tZM2jHvI2tkbJDQ==} + '@rolldown/binding-linux-s390x-gnu@1.1.5': + resolution: {integrity: sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] + libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.1': - resolution: {integrity: sha512-XABVmGp9Tg0WspTVvwduTc4fpqy6JnAUrSQe6OuyqD/03nI7r0O9OWUkMIwFrjKAIqolvqoA4ZrJppgwE0Gxmw==} + '@rolldown/binding-linux-x64-gnu@1.1.5': + resolution: {integrity: sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.0.1': - resolution: {integrity: sha512-bV4fzswuzVcKD90o/VM6QqKxnxlDq0g2BISDLNVmxrnhpv1DDbyPhCIjYfvzYLV+MvkKKnQt2Q6AO86SEBULUQ==} + '@rolldown/binding-linux-x64-musl@1.1.5': + resolution: {integrity: sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.1': - resolution: {integrity: sha512-/Mh0Zhq3OP7fVs0kcQHZP6lZEthMGTaSf8UBQYSFEZDWGXXlEC+nJ6EqenaK2t4LBXMe3A+K/G2BVXXdtOr4PQ==} + '@rolldown/binding-openharmony-arm64@1.1.5': + resolution: {integrity: sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.1': - resolution: {integrity: sha512-+1xc9X45l8ufsBAm6Gjvx2qDRIY9lTVt0cgWNcJ+1gdhXvkbxePA60yRTwSTuXL09CMhyJmjpV7E3NoyxbqFQQ==} + '@rolldown/binding-wasm32-wasi@1.1.5': + resolution: {integrity: sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.1': - resolution: {integrity: sha512-1D+UqZdfnuR+Jy1GgMJwi85bD40H21uNmOPRWQhw4oRSuolZ/B5rixZ45DK2KXOTCvmVCecauWgEhbw8bI7tOw==} + '@rolldown/binding-win32-arm64-msvc@1.1.5': + resolution: {integrity: sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.1': - resolution: {integrity: sha512-INAycaWuhlOK3wk4mRHGsdgwYWmd9cChdPdE9bwWmy6rn9VqVNYNFGhOdXrofXUxwHIncSiPNb8tNm8knDVIeQ==} + '@rolldown/binding-win32-x64-msvc@1.1.5': + resolution: {integrity: sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -308,6 +317,15 @@ packages: rollup: optional: true + '@rollup/plugin-replace@6.0.3': + resolution: {integrity: sha512-J4RZarRvQAm5IF0/LwUUg+obsm+xZhYnbMXmXROyoSE1ATJe3oXSb9L5MMppdxP2ylNSjv6zFBwKYjcKMucVfA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@rollup/pluginutils@5.3.0': resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} engines: {node: '>=14.0.0'} @@ -351,66 +369,79 @@ packages: resolution: {integrity: sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.60.4': resolution: {integrity: sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.60.4': resolution: {integrity: sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.60.4': resolution: {integrity: sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.60.4': resolution: {integrity: sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.60.4': resolution: {integrity: sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==} cpu: [loong64] os: [linux] + libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.60.4': resolution: {integrity: sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.60.4': resolution: {integrity: sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==} cpu: [ppc64] os: [linux] + libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.60.4': resolution: {integrity: sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.60.4': resolution: {integrity: sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.60.4': resolution: {integrity: sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.60.4': resolution: {integrity: sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.60.4': resolution: {integrity: sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-openbsd-x64@4.60.4': resolution: {integrity: sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==} @@ -450,13 +481,13 @@ packages: peerDependencies: acorn: ^8.9.0 - '@sveltejs/adapter-node@5.5.4': - resolution: {integrity: sha512-45X92CXW+2J8ZUzPv3eLlKWEzINKiiGeFWTjyER4ZN4sGgNoaoeSkCY/QYNxHpPXy71QPsctwccBo9jJs0ySPQ==} + '@sveltejs/adapter-node@5.5.7': + resolution: {integrity: sha512-uOfc9eVlI3A37RRSaKcgrheBYPrfJwC9VMqDp8x/O6tlKdcLLvHThSWD0KNIbjQ/d+7bwLGx3vx6aowAcRfd2g==} peerDependencies: '@sveltejs/kit': ^2.4.0 - '@sveltejs/kit@2.60.1': - resolution: {integrity: sha512-mQjlkNo+rJvpln7V2IGY2j99BqhcFbS4UN0AQNKNYfhBAFZTuCDAdW3a1sgf330mvtNvsBXn3HpAhcmvdJTcIQ==} + '@sveltejs/kit@2.70.1': + resolution: {integrity: sha512-nY9SPHGOZro3doud9vZXDBwl9tCZIouuJztjgSHs6PAIrv9M/z5O7eOhPV5xU7CgVHA976Jwu3BA1hIFvXztkA==} engines: {node: '>=18.13'} hasBin: true peerDependencies: @@ -471,72 +502,80 @@ packages: typescript: optional: true - '@sveltejs/vite-plugin-svelte@7.1.2': - resolution: {integrity: sha512-DrUBA2UXRfDmUX/ZTiEopd3X40yavsJF1FX2RygcuIScHL7o5YX1fMvoYnDhjeJQC4weCOklirpNWlcb2NiSeA==} + '@sveltejs/load-config@0.2.0': + resolution: {integrity: sha512-1LgZ/qUqSoq+QorD83lk2hka79Px0wXNW2q5V1nZlxGhQgw1jrsIbVz5YiCeucVLo4XvFLjXukUaQjIiqowkcg==} + engines: {node: '>= 18.0.0'} + + '@sveltejs/vite-plugin-svelte@7.2.0': + resolution: {integrity: sha512-1SpkuMSRLfugrVX+IrKfE1RUegzo8AQzKQ6qQPfVzbcWi5IhuTPaKb5ZrLpucleFznkc4/RTeSPoRnGWFxX+EQ==} engines: {node: ^20.19 || ^22.12 || >=24} peerDependencies: svelte: ^5.46.4 vite: ^8.0.0-beta.7 || ^8.0.0 - '@tailwindcss/node@4.3.0': - resolution: {integrity: sha512-aFb4gUhFOgdh9AXo4IzBEOzBkkAxm9VigwDJnMIYv3lcfXCJVesNfbEaBl4BNgVRyid92AmdviqwBUBRKSeY3g==} + '@tailwindcss/node@4.3.3': + resolution: {integrity: sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==} - '@tailwindcss/oxide-android-arm64@4.3.0': - resolution: {integrity: sha512-TJPiq67tKlLuObP6RkwvVGDoxCMBVtDgKkLfa/uyj7/FyxvQwHS+UOnVrXXgbEsfUaMgiVvC4KbJnRr26ho4Ng==} + '@tailwindcss/oxide-android-arm64@4.3.3': + resolution: {integrity: sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==} engines: {node: '>= 20'} cpu: [arm64] os: [android] - '@tailwindcss/oxide-darwin-arm64@4.3.0': - resolution: {integrity: sha512-oMN/WZRb+SO37BmUElEgeEWuU8E/HXRkiODxJxLe1UTHVXLrdVSgfaJV7pSlhRGMSOiXLuxTIjfsF3wYvz8cgQ==} + '@tailwindcss/oxide-darwin-arm64@4.3.3': + resolution: {integrity: sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==} engines: {node: '>= 20'} cpu: [arm64] os: [darwin] - '@tailwindcss/oxide-darwin-x64@4.3.0': - resolution: {integrity: sha512-N6CUmu4a6bKVADfw77p+iw6Yd9Q3OBhe0veaDX+QazfuVYlQsHfDgxBrsjQ/IW+zywL8mTrNd0SdJT/zgtvMdA==} + '@tailwindcss/oxide-darwin-x64@4.3.3': + resolution: {integrity: sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==} engines: {node: '>= 20'} cpu: [x64] os: [darwin] - '@tailwindcss/oxide-freebsd-x64@4.3.0': - resolution: {integrity: sha512-zDL5hBkQdH5C6MpqbK3gQAgP80tsMwSI26vjOzjJtNCMUo0lFgOItzHKBIupOZNQxt3ouPH7RPhvNhiTfCe5CQ==} + '@tailwindcss/oxide-freebsd-x64@4.3.3': + resolution: {integrity: sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==} engines: {node: '>= 20'} cpu: [x64] os: [freebsd] - '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.0': - resolution: {integrity: sha512-R06HdNi7A7OEoMsf6d4tjZ71RCWnZQPHj2mnotSFURjNLdBC+cIgXQ7l81CqeoiQftjf6OOblxXMInMgN2VzMA==} + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3': + resolution: {integrity: sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==} engines: {node: '>= 20'} cpu: [arm] os: [linux] - '@tailwindcss/oxide-linux-arm64-gnu@4.3.0': - resolution: {integrity: sha512-qTJHELX8jetjhRQHCLilkVLmybpzNQAtaI/gaoVoidn/ufbNDbAo8KlK2J+yPoc8wQxvDxCmh/5lr8nC1+lTbg==} + '@tailwindcss/oxide-linux-arm64-gnu@4.3.3': + resolution: {integrity: sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==} engines: {node: '>= 20'} cpu: [arm64] os: [linux] + libc: [glibc] - '@tailwindcss/oxide-linux-arm64-musl@4.3.0': - resolution: {integrity: sha512-Z6sukiQsngnWO+l39X4pPbiWT81IC+PLKF+PHxIlyZbGNb9MODfYlXEVlFvej5BOZInWX01kVyzeLvHsXhfczQ==} + '@tailwindcss/oxide-linux-arm64-musl@4.3.3': + resolution: {integrity: sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==} engines: {node: '>= 20'} cpu: [arm64] os: [linux] + libc: [musl] - '@tailwindcss/oxide-linux-x64-gnu@4.3.0': - resolution: {integrity: sha512-DRNdQRpSGzRGfARVuVkxvM8Q12nh19l4BF/G7zGA1oe+9wcC6saFBHTISrpIcKzhiXtSrlSrluCfvMuledoCTQ==} + '@tailwindcss/oxide-linux-x64-gnu@4.3.3': + resolution: {integrity: sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==} engines: {node: '>= 20'} cpu: [x64] os: [linux] + libc: [glibc] - '@tailwindcss/oxide-linux-x64-musl@4.3.0': - resolution: {integrity: sha512-Z0IADbDo8bh6I7h2IQMx601AdXBLfFpEdUotft86evd/8ZPflZe9COPO8Q1vw+pfLWIUo9zN/JGZvwuAJqduqg==} + '@tailwindcss/oxide-linux-x64-musl@4.3.3': + resolution: {integrity: sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==} engines: {node: '>= 20'} cpu: [x64] os: [linux] + libc: [musl] - '@tailwindcss/oxide-wasm32-wasi@4.3.0': - resolution: {integrity: sha512-HNZGOUxEmElksYR7S6sC5jTeNGpobAsy9u7Gu0AskJ8/20FR9GqebUyB+HBcU/ax6BHuiuJi+Oda4B+YX6H1yA==} + '@tailwindcss/oxide-wasm32-wasi@4.3.3': + resolution: {integrity: sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==} engines: {node: '>=14.0.0'} cpu: [wasm32] bundledDependencies: @@ -547,29 +586,29 @@ packages: - '@emnapi/wasi-threads' - tslib - '@tailwindcss/oxide-win32-arm64-msvc@4.3.0': - resolution: {integrity: sha512-Pe+RPVTi1T+qymuuRpcdvwSVZjnll/f7n8gBxMMh3xLTctMDKqpdfGimbMyioqtLhUYZxdJ9wGNhV7MKHvgZsQ==} + '@tailwindcss/oxide-win32-arm64-msvc@4.3.3': + resolution: {integrity: sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==} engines: {node: '>= 20'} cpu: [arm64] os: [win32] - '@tailwindcss/oxide-win32-x64-msvc@4.3.0': - resolution: {integrity: sha512-Mvrf2kXW/yeW/OTezZlCGOirXRcUuLIBx/5Y12BaPM7wJoryG6dfS/NJL8aBPqtTEx/Vm4T4vKzFUcKDT+TKUA==} + '@tailwindcss/oxide-win32-x64-msvc@4.3.3': + resolution: {integrity: sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==} engines: {node: '>= 20'} cpu: [x64] os: [win32] - '@tailwindcss/oxide@4.3.0': - resolution: {integrity: sha512-F7HZGBeN9I0/AuuJS5PwcD8xayx5ri5GhjYUDBEVYUkexyA/giwbDNjRVrxSezE3T250OU2K/wp/ltWx3UOefg==} + '@tailwindcss/oxide@4.3.3': + resolution: {integrity: sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==} engines: {node: '>= 20'} - '@tailwindcss/vite@4.3.0': - resolution: {integrity: sha512-t6J3OrB5Fc0ExuhohouH0fWUGMYL6PTLhW+E7zIk/pdbnJARZDCwjBznFnkh5ynRnIRSI4YjtTH0t6USjJISrw==} + '@tailwindcss/vite@4.3.3': + resolution: {integrity: sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw==} peerDependencies: vite: ^5.2.0 || ^6 || ^7 || ^8 - '@tybys/wasm-util@0.10.2': - resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} + '@tybys/wasm-util@0.10.3': + resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} '@types/cookie@0.6.0': resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} @@ -595,63 +634,63 @@ packages: '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} - '@typescript-eslint/eslint-plugin@8.59.4': - resolution: {integrity: sha512-PegsU+XfyJJNjd4+u/k6f9yTyp0lEXXiPopUNobZcIAUJFGICFLN+sP0Rb3JehVmiij1Ph0dFGYqODoRo/2+6A==} + '@typescript-eslint/eslint-plugin@8.64.0': + resolution: {integrity: sha512-CGvQPBxN3wZLu6Rz2kFUpZeoCm78xUic92ck39KPePkO1NPOwjCqdQnm5Q87tpWw9vcBvW8XLrDXjH9PWYtJ3Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.59.4 + '@typescript-eslint/parser': ^8.64.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.59.4': - resolution: {integrity: sha512-zORHqO/tuhxY1zWuTvMUqddRxpiFJ72xVfcNoWpqdLjs6lfPbuQBJuW4pk+49/uBMy7Ssr4bzgjiKmmDB1UbZQ==} + '@typescript-eslint/parser@8.64.0': + resolution: {integrity: sha512-KA0OshtlcCCXmbfqyZkM5pV3/WNraJf7DkJRLpyrmwPtud57H5BDX7C3k0LPSPxpprfRL+cJDGabF10mvNCoCw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.59.4': - resolution: {integrity: sha512-Ly00Vu4oAacfDeHp2Zg85ioNG6l8HG+tN1D7J+xTHSxu9y0awYKJ2zH1rFBn8ZSfuGK+7FxK3Cgl3uAz0aZZLg==} + '@typescript-eslint/project-service@8.64.0': + resolution: {integrity: sha512-tk4WpOJ6IEbGrVHaNmM0YRrwAD3exZlIK3iadQNAxh4YKk6jvUQ4ecq18n+v7+meh+cJ3j+D8nbk8sRKhlwLQg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.59.4': - resolution: {integrity: sha512-mUeR/3H1WrTAddJrwut8OoPjfauaztMQmRwV5fQTUyNVJCLiUXXe4lGEyYIL2oFDpP7UtgbGJXCt72wT0z2S3Q==} + '@typescript-eslint/scope-manager@8.64.0': + resolution: {integrity: sha512-CXEaFdYXjSTgKhisNkwCcJwTP8Pl+fmRrEQrri4nm3vU743bALrxzLmq7fHG/7e6a5xO0lDYeURpZmBuhHk54w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.59.4': - resolution: {integrity: sha512-DLCpnKgD4alVxTBSKulK+gU1KCqOgUXfDRDXh2mZgzokQKa/70ax93I2uVO3m/LLvIAtWZIFoiifudmIqAxpMA==} + '@typescript-eslint/tsconfig-utils@8.64.0': + resolution: {integrity: sha512-2yo8rRNKuzbVWQp5kslhANqZ2uDAeROQHBRZNPu8JDsHmeFNj/XJJhX/FhNUWmkHHvoNsKa6+tHJiig87EzsQw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.59.4': - resolution: {integrity: sha512-uonTuPAAKr9XaBGqJ3LjYTh72zy5DyGesljO9gtmk/eFW0W1fRHjnwVYKB35Lm8d5Q5CluEW3gPHjTvZTmgrfA==} + '@typescript-eslint/type-utils@8.64.0': + resolution: {integrity: sha512-XWG4Fmmv/6SvyS9nH8jWrKs6terwJvE8cyRt1CzYYqzp9OrPhCT4cMc/f7C6RZCwG+qMmiffJS1/qJP8G1URtg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.59.4': - resolution: {integrity: sha512-F1o7WJcCq+bc8dwcO/YsSEOudAH8RDtaOhM6wcAQhcUsFhnWQl81JKy48q1hoxAU0qrzM89+31GYh1515Zde3Q==} + '@typescript-eslint/types@8.64.0': + resolution: {integrity: sha512-qjhfuTfLXjA4IOzXvz0rTjT01BqEiIgPoUeMwiEjnaHKJMTNo8rH5pYW1a2L/0Dnux2fPC85AeyJoWaGa8WxTA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.59.4': - resolution: {integrity: sha512-F+RuOmcDXo4+TPdfd/TCLS3m2nw8gE9XXyZLrA3JBfaA5tz9TtdkyD3YJFmPxulyc2cKbEok/CvFE3MgSLWnag==} + '@typescript-eslint/typescript-estree@8.64.0': + resolution: {integrity: sha512-Pztpsn1aCE1oWDvDEfUk31nngvvF7vUB5SwHFEaZIFpvw7WJtqUHHL4plBZDA9HfWJJjL13BdG0YrJInTUvoVA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.59.4': - resolution: {integrity: sha512-cYXeNAUsG4lJo5dbc1FcKm+JwIWrj1/UpTORsC6tGMjEZ81DYcvIr9/ueikhMa/Y/gDQYGp+YX9/xQrXje5BJw==} + '@typescript-eslint/utils@8.64.0': + resolution: {integrity: sha512-aJUGVB3+U0htrrCjoA8qukw8cm8fNCGAxK/tVoS70k8aeb7DETKeFozRiVFIwEeN9WJLsjaP3ph8I60tY2XZoQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.59.4': - resolution: {integrity: sha512-U3gxVaDVnuZKhSspW/MzMxE1kq7zOdc072FcSNoqA1I9p8HyKbBFfEHoWckBAMgNMph4MamwS5iTVzFmrnt8TQ==} + '@typescript-eslint/visitor-keys@8.64.0': + resolution: {integrity: sha512-mrtuL8Nsn6gi2H4mo5KMTp823M+3Q19Ew/i+Zlikq20tIMm99C3Ez0dCmkWWnxut20esQvTg8aUSEhMcAOXhEw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} acorn-jsx@5.3.2: @@ -694,8 +733,8 @@ packages: commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - cookie@0.6.0: - resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} cross-spawn@7.0.6: @@ -730,8 +769,8 @@ packages: devalue@5.8.1: resolution: {integrity: sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==} - enhanced-resolve@5.21.6: - resolution: {integrity: sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ==} + enhanced-resolve@5.24.2: + resolution: {integrity: sha512-rpsZEGT1jFuve6QlpyRp9ckQ+kN61hvF9BzCPyMdaKTm8UJce96KBn3sorXOFXlzjPrs3Vc4T1NsSroZ3PxlFw==} engines: {node: '>=10.13.0'} es-errors@1.3.0: @@ -748,8 +787,8 @@ packages: peerDependencies: eslint: '>=7.0.0' - eslint-plugin-svelte@3.17.1: - resolution: {integrity: sha512-NyiXHtS3Ni7e532RBwS9OXlMKDIrENg3gY+/+ODjZzQx2xhU3NlJ+nIl1a93iUUQeiJL3lS8KLmY+W8hklzweQ==} + eslint-plugin-svelte@3.21.0: + resolution: {integrity: sha512-2dkuAk77FzQn5Ad5bJvcS6gU9iRCjywzQv6wVBR7RNseZzDsxfaIu+yzah/hTBB2znDd8Hl4oOISdhQuNyjTdQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.1 || ^9.0.0 || ^10.0.0 @@ -778,8 +817,8 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@10.4.0: - resolution: {integrity: sha512-loXy6bWOoP3EP6JA7jo6p5jMpBJmHmsNZM5SFRHLdh1MGOPurMnNBj4ZlAbaqUAaQWbCr7jHV4P7gzAyryZWkQ==} + eslint@10.7.0: + resolution: {integrity: sha512-GVTD7s1vdIl6UYvAfriOPeY1Df8LIZjfofLvHwde+erDHGGuHyuM6xoxRxmHiebhYuD2p1vN4wWh0XzPARSGDQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} hasBin: true peerDependencies: @@ -803,8 +842,8 @@ packages: resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} engines: {node: '>=0.10'} - esrap@2.2.9: - resolution: {integrity: sha512-4KijP+NxCWthMCUC3qHbE6n4vCjqgJS1uAYKhuT/GWfFTf1Qyive2TgOjep+gzbSzRfnNyaN/UU9YmdOt8Eg0A==} + esrap@2.3.0: + resolution: {integrity: sha512-GQ/7RN8uOtEfNpzZzBMTzW9JBcX42oaSVtPzdF+6cEL8pqIL094iUpr9jzYGn4O4P/1S60dJ6izyT8F4LYARng==} peerDependencies: '@typescript-eslint/types': ^8.2.0 peerDependenciesMeta: @@ -878,8 +917,8 @@ packages: resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} engines: {node: '>=18'} - globals@17.6.0: - resolution: {integrity: sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==} + globals@17.7.0: + resolution: {integrity: sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg==} engines: {node: '>=18'} graceful-fs@4.2.11: @@ -990,24 +1029,28 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-musl@1.32.0: resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-x64-gnu@1.32.0: resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-musl@1.32.0: resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-win32-arm64-msvc@1.32.0: resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} @@ -1098,6 +1141,10 @@ packages: resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} + engines: {node: '>=12'} + postcss-load-config@3.1.4: resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} engines: {node: '>= 10'} @@ -1130,18 +1177,23 @@ packages: resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} engines: {node: ^10 || ^12 || >=14} + postcss@8.5.19: + resolution: {integrity: sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ==} + engines: {node: ^10 || ^12 || >=14} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier-plugin-svelte@3.5.2: - resolution: {integrity: sha512-ItFouLvzSFE3ulNl4DKoWM3BGcbDCNVpIyy/Y3F2gC3aNiGLxtFUdffVqO5Z5hhYG+DFT5KULWaxmeFFpdbvaQ==} + prettier-plugin-svelte@4.1.1: + resolution: {integrity: sha512-wXvbXMjSvb4C9ENWTHXyd+ihakKCsJ6rJhLP6/8HFNj4GkZr48jqL9PoKsl2sk7SyCZRTnJ7O2TTowUpOxP/KA==} + engines: {node: '>=20'} peerDependencies: prettier: ^3.0.0 - svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0 + svelte: ^5.0.0 - prettier-plugin-tailwindcss@0.7.4: - resolution: {integrity: sha512-UKii4RjY05SNt/WQi6/NcOn/LsT0/ILLXsxygjbRg5/YZelsSu5jTqorYHPDGq4nZy5q5hpCu+XdGZ1xaJEQgw==} + prettier-plugin-tailwindcss@0.8.1: + resolution: {integrity: sha512-iaFMYqDsE4ffdDkn5qup0j5f2aCEBFZrdrZnvu9QKTlWx/iGPeQ4HHu7b7fCPMxeo9nwQBiOAh2nSypdFYWJkw==} engines: {node: '>=20.19'} peerDependencies: '@ianvs/prettier-plugin-sort-imports': '*' @@ -1195,8 +1247,8 @@ packages: prettier-plugin-svelte: optional: true - prettier@3.8.3: - resolution: {integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==} + prettier@3.9.5: + resolution: {integrity: sha512-/FVl766LpUfB5vXgCYOYa0MeV/441Ia99AeICQIQFTY/Nw0roZwULcXpku5i1/m5kt/baz+s4Zogspd839HSMg==} engines: {node: '>=14'} hasBin: true @@ -1213,8 +1265,8 @@ packages: engines: {node: '>= 0.4'} hasBin: true - rolldown@1.0.1: - resolution: {integrity: sha512-X0KQHljNnEkWNqqiz9zJrGunh1B0HgOxLXvnFpCOcadzcy5qohZ3tqMEUg00vncoRovXuK3ZqCT9KnnKzoInFQ==} + rolldown@1.1.5: + resolution: {integrity: sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -1255,32 +1307,32 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - svelte-check@4.4.8: - resolution: {integrity: sha512-67adfgBox5eNSNIvIIwgFizKGdcRrGpiMoNO2obHcYuLz7iTa8Xgm/NGU3ntMFnNm8K1grFOIG6HhMLX/vcN8w==} + svelte-check@4.7.3: + resolution: {integrity: sha512-DHdTCGX62R0fCxBEaT+USdASAnoaRBaaNczkRJl0K7o3WyoCeVUbVxo6fKqpOll/B+WMWCsiFK0eFrJSNBKZIg==} engines: {node: '>= 18.0.0'} hasBin: true peerDependencies: svelte: ^4.0.0 || ^5.0.0-next.0 typescript: '>=5.0.0' - svelte-eslint-parser@1.6.1: - resolution: {integrity: sha512-hhvSH6kRj46UzrBVO5TaotD+Iuvruj5ccKBcO4wAhVcPTLmIc/c32D8UllBTYO0on4LzYuM0rNzf1lM/gBlkSQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0, pnpm: 10.33.0} + svelte-eslint-parser@1.8.0: + resolution: {integrity: sha512-mikR1qwIVy3t5WthUoAXkMwxkXvabZP9FJgdx35Ei7EbGWmctva1Pih16Koeor/bdNNq8NXHlwKGS6NkYTawLg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0, pnpm: 10.34.1} peerDependencies: svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 peerDependenciesMeta: svelte: optional: true - svelte@5.55.9: - resolution: {integrity: sha512-fTjjT8cHLDwigcu2j3pv7Jq04LklXevPB8uBgyHNiTXv+RMNvVnrjS4UEYrLMkhuq1vpCodHjiW+z/95SDs/fg==} + svelte@5.56.6: + resolution: {integrity: sha512-p4HDLDogGHKRKCrgckQHNs5PEfXkju6JI5jTywueaKJI5hAdjPohEhRtQ0M1SWC/+TA73SPln+r7srr+7e4nZA==} engines: {node: '>=18'} tailwind-merge@3.6.0: resolution: {integrity: sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==} - tailwindcss@4.3.0: - resolution: {integrity: sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q==} + tailwindcss@4.3.3: + resolution: {integrity: sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==} tapable@2.3.3: resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} @@ -1290,6 +1342,10 @@ packages: resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + totalist@3.0.1: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} @@ -1307,8 +1363,8 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - typescript-eslint@8.59.4: - resolution: {integrity: sha512-Rw6+44QNFaXtgHSjPy+Kw8hrJniMYzR85E9yLmOLcfZ91/rz+JXQbDTCmc6ccxMPY6K6PgAq26f0JCBfR7LIPQ==} + typescript-eslint@8.64.0: + resolution: {integrity: sha512-0qg+pDNMnqYzqH9AnNK+39tejHvsShUOUUoRUgtnTGE7QuMZhiFDnozq8nHJVq+Wae6NMLKNWLg5WmkcC/ndyQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -1328,13 +1384,13 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - vite@8.0.13: - resolution: {integrity: sha512-MFtjBYgzmSxmgA4RAfjIyXWpGe1oALnjgUTzzV7QLx/TKxCzjtMH6Fd9/eVK+5Fg1qNoz5VAwsmMs/NofrmJvw==} + vite@8.1.5: + resolution: {integrity: sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.1.18 + '@vitejs/devtools': ^0.3.0 esbuild: ^0.27.0 || ^0.28.0 jiti: '>=1.21.0' less: ^4.0.0 @@ -1401,34 +1457,34 @@ packages: snapshots: - '@emnapi/core@1.10.0': + '@emnapi/core@1.11.1': dependencies: - '@emnapi/wasi-threads': 1.2.1 + '@emnapi/wasi-threads': 1.2.2 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.10.0': + '@emnapi/runtime@1.11.1': dependencies: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.2.1': + '@emnapi/wasi-threads@1.2.2': dependencies: tslib: 2.8.1 optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@10.4.0(jiti@2.7.0))': + '@eslint-community/eslint-utils@4.9.1(eslint@10.7.0(jiti@2.7.0))': dependencies: - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.7.0(jiti@2.7.0) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} - '@eslint/compat@2.1.0(eslint@10.4.0(jiti@2.7.0))': + '@eslint/compat@2.1.0(eslint@10.7.0(jiti@2.7.0))': dependencies: '@eslint/core': 1.2.1 optionalDependencies: - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.7.0(jiti@2.7.0) '@eslint/config-array@0.23.5': dependencies: @@ -1446,13 +1502,13 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/js@10.0.1(eslint@10.4.0(jiti@2.7.0))': + '@eslint/js@10.0.1(eslint@10.7.0(jiti@2.7.0))': optionalDependencies: - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.7.0(jiti@2.7.0) '@eslint/object-schema@3.0.5': {} - '@eslint/plugin-kit@0.7.1': + '@eslint/plugin-kit@0.7.2': dependencies: '@eslint/core': 1.2.1 levn: 0.4.1 @@ -1492,64 +1548,64 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@tybys/wasm-util': 0.10.2 + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@tybys/wasm-util': 0.10.3 optional: true - '@oxc-project/types@0.130.0': {} + '@oxc-project/types@0.139.0': {} '@polka/url@1.0.0-next.29': {} - '@rolldown/binding-android-arm64@1.0.1': + '@rolldown/binding-android-arm64@1.1.5': optional: true - '@rolldown/binding-darwin-arm64@1.0.1': + '@rolldown/binding-darwin-arm64@1.1.5': optional: true - '@rolldown/binding-darwin-x64@1.0.1': + '@rolldown/binding-darwin-x64@1.1.5': optional: true - '@rolldown/binding-freebsd-x64@1.0.1': + '@rolldown/binding-freebsd-x64@1.1.5': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.1': + '@rolldown/binding-linux-arm-gnueabihf@1.1.5': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.1': + '@rolldown/binding-linux-arm64-gnu@1.1.5': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.1': + '@rolldown/binding-linux-arm64-musl@1.1.5': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.1': + '@rolldown/binding-linux-ppc64-gnu@1.1.5': optional: true - '@rolldown/binding-linux-s390x-gnu@1.0.1': + '@rolldown/binding-linux-s390x-gnu@1.1.5': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.1': + '@rolldown/binding-linux-x64-gnu@1.1.5': optional: true - '@rolldown/binding-linux-x64-musl@1.0.1': + '@rolldown/binding-linux-x64-musl@1.1.5': optional: true - '@rolldown/binding-openharmony-arm64@1.0.1': + '@rolldown/binding-openharmony-arm64@1.1.5': optional: true - '@rolldown/binding-wasm32-wasi@1.0.1': + '@rolldown/binding-wasm32-wasi@1.1.5': dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.1': + '@rolldown/binding-win32-arm64-msvc@1.1.5': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.1': + '@rolldown/binding-win32-x64-msvc@1.1.5': optional: true '@rolldown/pluginutils@1.0.1': {} @@ -1582,6 +1638,13 @@ snapshots: optionalDependencies: rollup: 4.60.4 + '@rollup/plugin-replace@6.0.3(rollup@4.60.4)': + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.60.4) + magic-string: 0.30.21 + optionalDependencies: + rollup: 4.60.4 + '@rollup/pluginutils@5.3.0(rollup@4.60.4)': dependencies: '@types/estree': 1.0.9 @@ -1671,22 +1734,23 @@ snapshots: dependencies: acorn: 8.16.0 - '@sveltejs/adapter-node@5.5.4(@sveltejs/kit@2.60.1(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(jiti@2.7.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(jiti@2.7.0)))': + '@sveltejs/adapter-node@5.5.7(@sveltejs/kit@2.70.1(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.6(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)))(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3)(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)))': dependencies: '@rollup/plugin-commonjs': 29.0.2(rollup@4.60.4) '@rollup/plugin-json': 6.1.0(rollup@4.60.4) '@rollup/plugin-node-resolve': 16.0.3(rollup@4.60.4) - '@sveltejs/kit': 2.60.1(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(jiti@2.7.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(jiti@2.7.0)) + '@rollup/plugin-replace': 6.0.3(rollup@4.60.4) + '@sveltejs/kit': 2.70.1(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.6(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)))(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3)(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)) rollup: 4.60.4 - '@sveltejs/kit@2.60.1(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(jiti@2.7.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(jiti@2.7.0))': + '@sveltejs/kit@2.70.1(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.6(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)))(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3)(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0))': dependencies: '@standard-schema/spec': 1.1.0 '@sveltejs/acorn-typescript': 1.0.10(acorn@8.16.0) - '@sveltejs/vite-plugin-svelte': 7.1.2(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(jiti@2.7.0)) + '@sveltejs/vite-plugin-svelte': 7.2.0(svelte@5.56.6(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)) '@types/cookie': 0.6.0 acorn: 8.16.0 - cookie: 0.6.0 + cookie: 0.7.2 devalue: 5.8.1 esm-env: 1.2.2 kleur: 4.1.5 @@ -1694,89 +1758,91 @@ snapshots: mrmime: 2.0.1 set-cookie-parser: 3.1.0 sirv: 3.0.2 - svelte: 5.55.9(@typescript-eslint/types@8.59.4) - vite: 8.0.13(@types/node@24.12.4)(jiti@2.7.0) + svelte: 5.56.6(@typescript-eslint/types@8.64.0) + vite: 8.1.5(@types/node@24.12.4)(jiti@2.7.0) optionalDependencies: typescript: 6.0.3 - '@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(jiti@2.7.0))': + '@sveltejs/load-config@0.2.0': {} + + '@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.6(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0))': dependencies: deepmerge: 4.3.1 magic-string: 0.30.21 obug: 2.1.1 - svelte: 5.55.9(@typescript-eslint/types@8.59.4) - vite: 8.0.13(@types/node@24.12.4)(jiti@2.7.0) - vitefu: 1.1.3(vite@8.0.13(@types/node@24.12.4)(jiti@2.7.0)) + svelte: 5.56.6(@typescript-eslint/types@8.64.0) + vite: 8.1.5(@types/node@24.12.4)(jiti@2.7.0) + vitefu: 1.1.3(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)) - '@tailwindcss/node@4.3.0': + '@tailwindcss/node@4.3.3': dependencies: '@jridgewell/remapping': 2.3.5 - enhanced-resolve: 5.21.6 + enhanced-resolve: 5.24.2 jiti: 2.7.0 lightningcss: 1.32.0 magic-string: 0.30.21 source-map-js: 1.2.1 - tailwindcss: 4.3.0 + tailwindcss: 4.3.3 - '@tailwindcss/oxide-android-arm64@4.3.0': + '@tailwindcss/oxide-android-arm64@4.3.3': optional: true - '@tailwindcss/oxide-darwin-arm64@4.3.0': + '@tailwindcss/oxide-darwin-arm64@4.3.3': optional: true - '@tailwindcss/oxide-darwin-x64@4.3.0': + '@tailwindcss/oxide-darwin-x64@4.3.3': optional: true - '@tailwindcss/oxide-freebsd-x64@4.3.0': + '@tailwindcss/oxide-freebsd-x64@4.3.3': optional: true - '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.0': + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3': optional: true - '@tailwindcss/oxide-linux-arm64-gnu@4.3.0': + '@tailwindcss/oxide-linux-arm64-gnu@4.3.3': optional: true - '@tailwindcss/oxide-linux-arm64-musl@4.3.0': + '@tailwindcss/oxide-linux-arm64-musl@4.3.3': optional: true - '@tailwindcss/oxide-linux-x64-gnu@4.3.0': + '@tailwindcss/oxide-linux-x64-gnu@4.3.3': optional: true - '@tailwindcss/oxide-linux-x64-musl@4.3.0': + '@tailwindcss/oxide-linux-x64-musl@4.3.3': optional: true - '@tailwindcss/oxide-wasm32-wasi@4.3.0': + '@tailwindcss/oxide-wasm32-wasi@4.3.3': optional: true - '@tailwindcss/oxide-win32-arm64-msvc@4.3.0': + '@tailwindcss/oxide-win32-arm64-msvc@4.3.3': optional: true - '@tailwindcss/oxide-win32-x64-msvc@4.3.0': + '@tailwindcss/oxide-win32-x64-msvc@4.3.3': optional: true - '@tailwindcss/oxide@4.3.0': + '@tailwindcss/oxide@4.3.3': optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.3.0 - '@tailwindcss/oxide-darwin-arm64': 4.3.0 - '@tailwindcss/oxide-darwin-x64': 4.3.0 - '@tailwindcss/oxide-freebsd-x64': 4.3.0 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.0 - '@tailwindcss/oxide-linux-arm64-gnu': 4.3.0 - '@tailwindcss/oxide-linux-arm64-musl': 4.3.0 - '@tailwindcss/oxide-linux-x64-gnu': 4.3.0 - '@tailwindcss/oxide-linux-x64-musl': 4.3.0 - '@tailwindcss/oxide-wasm32-wasi': 4.3.0 - '@tailwindcss/oxide-win32-arm64-msvc': 4.3.0 - '@tailwindcss/oxide-win32-x64-msvc': 4.3.0 + '@tailwindcss/oxide-android-arm64': 4.3.3 + '@tailwindcss/oxide-darwin-arm64': 4.3.3 + '@tailwindcss/oxide-darwin-x64': 4.3.3 + '@tailwindcss/oxide-freebsd-x64': 4.3.3 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.3 + '@tailwindcss/oxide-linux-arm64-gnu': 4.3.3 + '@tailwindcss/oxide-linux-arm64-musl': 4.3.3 + '@tailwindcss/oxide-linux-x64-gnu': 4.3.3 + '@tailwindcss/oxide-linux-x64-musl': 4.3.3 + '@tailwindcss/oxide-wasm32-wasi': 4.3.3 + '@tailwindcss/oxide-win32-arm64-msvc': 4.3.3 + '@tailwindcss/oxide-win32-x64-msvc': 4.3.3 - '@tailwindcss/vite@4.3.0(vite@8.0.13(@types/node@24.12.4)(jiti@2.7.0))': + '@tailwindcss/vite@4.3.3(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0))': dependencies: - '@tailwindcss/node': 4.3.0 - '@tailwindcss/oxide': 4.3.0 - tailwindcss: 4.3.0 - vite: 8.0.13(@types/node@24.12.4)(jiti@2.7.0) + '@tailwindcss/node': 4.3.3 + '@tailwindcss/oxide': 4.3.3 + tailwindcss: 4.3.3 + vite: 8.1.5(@types/node@24.12.4)(jiti@2.7.0) - '@tybys/wasm-util@0.10.2': + '@tybys/wasm-util@0.10.3': dependencies: tslib: 2.8.1 optional: true @@ -1799,15 +1865,15 @@ snapshots: '@types/trusted-types@2.0.7': {} - '@typescript-eslint/eslint-plugin@8.59.4(@typescript-eslint/parser@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.64.0(@typescript-eslint/parser@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.59.4 - '@typescript-eslint/type-utils': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/utils': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.59.4 - eslint: 10.4.0(jiti@2.7.0) + '@typescript-eslint/parser': 8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.64.0 + '@typescript-eslint/type-utils': 8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/utils': 8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.64.0 + eslint: 10.7.0(jiti@2.7.0) ignore: 7.0.5 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -1815,56 +1881,56 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/parser@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@typescript-eslint/scope-manager': 8.59.4 - '@typescript-eslint/types': 8.59.4 - '@typescript-eslint/typescript-estree': 8.59.4(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.59.4 + '@typescript-eslint/scope-manager': 8.64.0 + '@typescript-eslint/types': 8.64.0 + '@typescript-eslint/typescript-estree': 8.64.0(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.64.0 debug: 4.4.3 - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.7.0(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.59.4(typescript@6.0.3)': + '@typescript-eslint/project-service@8.64.0(typescript@6.0.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.59.4(typescript@6.0.3) - '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/tsconfig-utils': 8.64.0(typescript@6.0.3) + '@typescript-eslint/types': 8.64.0 debug: 4.4.3 typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.59.4': + '@typescript-eslint/scope-manager@8.64.0': dependencies: - '@typescript-eslint/types': 8.59.4 - '@typescript-eslint/visitor-keys': 8.59.4 + '@typescript-eslint/types': 8.64.0 + '@typescript-eslint/visitor-keys': 8.64.0 - '@typescript-eslint/tsconfig-utils@8.59.4(typescript@6.0.3)': + '@typescript-eslint/tsconfig-utils@8.64.0(typescript@6.0.3)': dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.59.4 - '@typescript-eslint/typescript-estree': 8.59.4(typescript@6.0.3) - '@typescript-eslint/utils': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/types': 8.64.0 + '@typescript-eslint/typescript-estree': 8.64.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3) debug: 4.4.3 - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.7.0(jiti@2.7.0) ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.59.4': {} + '@typescript-eslint/types@8.64.0': {} - '@typescript-eslint/typescript-estree@8.59.4(typescript@6.0.3)': + '@typescript-eslint/typescript-estree@8.64.0(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.59.4(typescript@6.0.3) - '@typescript-eslint/tsconfig-utils': 8.59.4(typescript@6.0.3) - '@typescript-eslint/types': 8.59.4 - '@typescript-eslint/visitor-keys': 8.59.4 + '@typescript-eslint/project-service': 8.64.0(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.64.0(typescript@6.0.3) + '@typescript-eslint/types': 8.64.0 + '@typescript-eslint/visitor-keys': 8.64.0 debug: 4.4.3 minimatch: 10.2.5 semver: 7.8.0 @@ -1874,20 +1940,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/utils@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.0(jiti@2.7.0)) - '@typescript-eslint/scope-manager': 8.59.4 - '@typescript-eslint/types': 8.59.4 - '@typescript-eslint/typescript-estree': 8.59.4(typescript@6.0.3) - eslint: 10.4.0(jiti@2.7.0) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.7.0(jiti@2.7.0)) + '@typescript-eslint/scope-manager': 8.64.0 + '@typescript-eslint/types': 8.64.0 + '@typescript-eslint/typescript-estree': 8.64.0(typescript@6.0.3) + eslint: 10.7.0(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.59.4': + '@typescript-eslint/visitor-keys@8.64.0': dependencies: - '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/types': 8.64.0 eslint-visitor-keys: 5.0.1 acorn-jsx@5.3.2(acorn@8.16.0): @@ -1921,7 +1987,7 @@ snapshots: commondir@1.0.1: {} - cookie@0.6.0: {} + cookie@0.7.2: {} cross-spawn@7.0.6: dependencies: @@ -1943,7 +2009,7 @@ snapshots: devalue@5.8.1: {} - enhanced-resolve@5.21.6: + enhanced-resolve@5.24.2: dependencies: graceful-fs: 4.2.11 tapable: 2.3.3 @@ -1952,15 +2018,15 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@10.4.0(jiti@2.7.0)): + eslint-config-prettier@10.1.8(eslint@10.7.0(jiti@2.7.0)): dependencies: - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.7.0(jiti@2.7.0) - eslint-plugin-svelte@3.17.1(eslint@10.4.0(jiti@2.7.0))(svelte@5.55.9(@typescript-eslint/types@8.59.4)): + eslint-plugin-svelte@3.21.0(eslint@10.7.0(jiti@2.7.0))(svelte@5.56.6(@typescript-eslint/types@8.64.0)): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.0(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.7.0(jiti@2.7.0)) '@jridgewell/sourcemap-codec': 1.5.5 - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.7.0(jiti@2.7.0) esutils: 2.0.3 globals: 16.5.0 known-css-properties: 0.37.0 @@ -1968,9 +2034,9 @@ snapshots: postcss-load-config: 3.1.4(postcss@8.5.15) postcss-safe-parser: 7.0.1(postcss@8.5.15) semver: 7.8.0 - svelte-eslint-parser: 1.6.1(svelte@5.55.9(@typescript-eslint/types@8.59.4)) + svelte-eslint-parser: 1.8.0(svelte@5.56.6(@typescript-eslint/types@8.64.0)) optionalDependencies: - svelte: 5.55.9(@typescript-eslint/types@8.59.4) + svelte: 5.56.6(@typescript-eslint/types@8.64.0) transitivePeerDependencies: - ts-node @@ -1992,14 +2058,14 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.4.0(jiti@2.7.0): + eslint@10.7.0(jiti@2.7.0): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.0(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.7.0(jiti@2.7.0)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.23.5 '@eslint/config-helpers': 0.6.0 '@eslint/core': 1.2.1 - '@eslint/plugin-kit': 0.7.1 + '@eslint/plugin-kit': 0.7.2 '@humanfs/node': 0.16.8 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 @@ -2047,11 +2113,11 @@ snapshots: dependencies: estraverse: 5.3.0 - esrap@2.2.9(@typescript-eslint/types@8.59.4): + esrap@2.3.0(@typescript-eslint/types@8.64.0): dependencies: '@jridgewell/sourcemap-codec': 1.5.5 optionalDependencies: - '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/types': 8.64.0 esrecurse@4.3.0: dependencies: @@ -2102,7 +2168,7 @@ snapshots: globals@16.5.0: {} - globals@17.6.0: {} + globals@17.7.0: {} graceful-fs@4.2.11: {} @@ -2269,6 +2335,8 @@ snapshots: picomatch@4.0.4: {} + picomatch@4.0.5: {} + postcss-load-config@3.1.4(postcss@8.5.15): dependencies: lilconfig: 2.1.0 @@ -2295,20 +2363,26 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + postcss@8.5.19: + dependencies: + nanoid: 3.3.12 + picocolors: 1.1.1 + source-map-js: 1.2.1 + prelude-ls@1.2.1: {} - prettier-plugin-svelte@3.5.2(prettier@3.8.3)(svelte@5.55.9(@typescript-eslint/types@8.59.4)): + prettier-plugin-svelte@4.1.1(prettier@3.9.5)(svelte@5.56.6(@typescript-eslint/types@8.64.0)): dependencies: - prettier: 3.8.3 - svelte: 5.55.9(@typescript-eslint/types@8.59.4) + prettier: 3.9.5 + svelte: 5.56.6(@typescript-eslint/types@8.64.0) - prettier-plugin-tailwindcss@0.7.4(prettier-plugin-svelte@3.5.2(prettier@3.8.3)(svelte@5.55.9(@typescript-eslint/types@8.59.4)))(prettier@3.8.3): + prettier-plugin-tailwindcss@0.8.1(prettier-plugin-svelte@4.1.1(prettier@3.9.5)(svelte@5.56.6(@typescript-eslint/types@8.64.0)))(prettier@3.9.5): dependencies: - prettier: 3.8.3 + prettier: 3.9.5 optionalDependencies: - prettier-plugin-svelte: 3.5.2(prettier@3.8.3)(svelte@5.55.9(@typescript-eslint/types@8.59.4)) + prettier-plugin-svelte: 4.1.1(prettier@3.9.5)(svelte@5.56.6(@typescript-eslint/types@8.64.0)) - prettier@3.8.3: {} + prettier@3.9.5: {} punycode@2.3.1: {} @@ -2321,26 +2395,26 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - rolldown@1.0.1: + rolldown@1.1.5: dependencies: - '@oxc-project/types': 0.130.0 + '@oxc-project/types': 0.139.0 '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.1 - '@rolldown/binding-darwin-arm64': 1.0.1 - '@rolldown/binding-darwin-x64': 1.0.1 - '@rolldown/binding-freebsd-x64': 1.0.1 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.1 - '@rolldown/binding-linux-arm64-gnu': 1.0.1 - '@rolldown/binding-linux-arm64-musl': 1.0.1 - '@rolldown/binding-linux-ppc64-gnu': 1.0.1 - '@rolldown/binding-linux-s390x-gnu': 1.0.1 - '@rolldown/binding-linux-x64-gnu': 1.0.1 - '@rolldown/binding-linux-x64-musl': 1.0.1 - '@rolldown/binding-openharmony-arm64': 1.0.1 - '@rolldown/binding-wasm32-wasi': 1.0.1 - '@rolldown/binding-win32-arm64-msvc': 1.0.1 - '@rolldown/binding-win32-x64-msvc': 1.0.1 + '@rolldown/binding-android-arm64': 1.1.5 + '@rolldown/binding-darwin-arm64': 1.1.5 + '@rolldown/binding-darwin-x64': 1.1.5 + '@rolldown/binding-freebsd-x64': 1.1.5 + '@rolldown/binding-linux-arm-gnueabihf': 1.1.5 + '@rolldown/binding-linux-arm64-gnu': 1.1.5 + '@rolldown/binding-linux-arm64-musl': 1.1.5 + '@rolldown/binding-linux-ppc64-gnu': 1.1.5 + '@rolldown/binding-linux-s390x-gnu': 1.1.5 + '@rolldown/binding-linux-x64-gnu': 1.1.5 + '@rolldown/binding-linux-x64-musl': 1.1.5 + '@rolldown/binding-openharmony-arm64': 1.1.5 + '@rolldown/binding-wasm32-wasi': 1.1.5 + '@rolldown/binding-win32-arm64-msvc': 1.1.5 + '@rolldown/binding-win32-x64-msvc': 1.1.5 rollup@4.60.4: dependencies: @@ -2397,19 +2471,20 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte-check@4.4.8(picomatch@4.0.4)(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@6.0.3): + svelte-check@4.7.3(picomatch@4.0.4)(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3): dependencies: '@jridgewell/trace-mapping': 0.3.31 + '@sveltejs/load-config': 0.2.0 chokidar: 4.0.3 fdir: 6.5.0(picomatch@4.0.4) picocolors: 1.1.1 sade: 1.8.1 - svelte: 5.55.9(@typescript-eslint/types@8.59.4) + svelte: 5.56.6(@typescript-eslint/types@8.64.0) typescript: 6.0.3 transitivePeerDependencies: - picomatch - svelte-eslint-parser@1.6.1(svelte@5.55.9(@typescript-eslint/types@8.59.4)): + svelte-eslint-parser@1.8.0(svelte@5.56.6(@typescript-eslint/types@8.64.0)): dependencies: eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -2419,9 +2494,9 @@ snapshots: postcss-selector-parser: 7.1.1 semver: 7.8.0 optionalDependencies: - svelte: 5.55.9(@typescript-eslint/types@8.59.4) + svelte: 5.56.6(@typescript-eslint/types@8.64.0) - svelte@5.55.9(@typescript-eslint/types@8.59.4): + svelte@5.56.6(@typescript-eslint/types@8.64.0): dependencies: '@jridgewell/remapping': 2.3.5 '@jridgewell/sourcemap-codec': 1.5.5 @@ -2434,7 +2509,7 @@ snapshots: clsx: 2.1.1 devalue: 5.8.1 esm-env: 1.2.2 - esrap: 2.2.9(@typescript-eslint/types@8.59.4) + esrap: 2.3.0(@typescript-eslint/types@8.64.0) is-reference: 3.0.3 locate-character: 3.0.0 magic-string: 0.30.21 @@ -2444,7 +2519,7 @@ snapshots: tailwind-merge@3.6.0: {} - tailwindcss@4.3.0: {} + tailwindcss@4.3.3: {} tapable@2.3.3: {} @@ -2453,6 +2528,11 @@ snapshots: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + totalist@3.0.1: {} ts-api-utils@2.5.0(typescript@6.0.3): @@ -2466,13 +2546,13 @@ snapshots: dependencies: prelude-ls: 1.2.1 - typescript-eslint@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3): + typescript-eslint@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.59.4(@typescript-eslint/parser@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/parser': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/typescript-estree': 8.59.4(typescript@6.0.3) - '@typescript-eslint/utils': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) - eslint: 10.4.0(jiti@2.7.0) + '@typescript-eslint/eslint-plugin': 8.64.0(@typescript-eslint/parser@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/parser': 8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.64.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3) + eslint: 10.7.0(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -2487,21 +2567,21 @@ snapshots: util-deprecate@1.0.2: {} - vite@8.0.13(@types/node@24.12.4)(jiti@2.7.0): + vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0): dependencies: lightningcss: 1.32.0 - picomatch: 4.0.4 - postcss: 8.5.15 - rolldown: 1.0.1 - tinyglobby: 0.2.16 + picomatch: 4.0.5 + postcss: 8.5.19 + rolldown: 1.1.5 + tinyglobby: 0.2.17 optionalDependencies: '@types/node': 24.12.4 fsevents: 2.3.3 jiti: 2.7.0 - vitefu@1.1.3(vite@8.0.13(@types/node@24.12.4)(jiti@2.7.0)): + vitefu@1.1.3(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)): optionalDependencies: - vite: 8.0.13(@types/node@24.12.4)(jiti@2.7.0) + vite: 8.1.5(@types/node@24.12.4)(jiti@2.7.0) which@2.0.2: dependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 5b23a1c..5fff66b 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,13 @@ +packages: + - . + +minimumReleaseAgeExclude: + - '@sveltejs/kit@2.70.1' + - eslint-plugin-svelte@3.21.0 + +overrides: + cookie: 0.7.2 + onlyBuiltDependencies: - '@tailwindcss/oxide' - esbuild diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..c072508 --- /dev/null +++ b/renovate.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["config:recommended"], + "dependencyDashboard": true, + "labels": ["dependencies"], + "packageRules": [ + { + "matchManagers": ["npm"], + "rangeStrategy": "pin" + }, + { + "matchDatasources": ["docker"], + "pinDigests": true + } + ] +} diff --git a/src/app.html b/src/app.html index 6a2bb58..7d565ba 100644 --- a/src/app.html +++ b/src/app.html @@ -1,9 +1,8 @@ - + - %sveltekit.head% diff --git a/src/lib/blog/posts.ts b/src/lib/blog/posts.ts index 50fc447..54bcbaa 100644 --- a/src/lib/blog/posts.ts +++ b/src/lib/blog/posts.ts @@ -1,11 +1,25 @@ -export type Post = { +export type PostContentBlock = + | { + type: 'paragraph'; + text: string; + } + | { + type: 'heading'; + text: string; + } + | { + type: 'list'; + items: string[]; + }; + +export type Post = { id: number; slug: string; date: string; title: string; description: string; tags: string[]; - content: string; + content: PostContentBlock[]; }; export const posts: Post[] = [ @@ -17,50 +31,85 @@ export const posts: Post[] = [ description: 'Как использовать уровни Stop Loss и Take Profit для грамотного управления капиталом при работе с прогнозами.', tags: ['RISK', 'TRADING', 'EDUCATION'], - content: ` -

Управление рисками — фундамент любой торговой стратегии. Без него даже точный ML-прогноз не поможет сохранить капитал.

-

Stop Loss: где ваша позиция неправа

-

Stop Loss — уровень, при достижении которого позиция закрывается автоматически. Это не признание ошибки, а часть стратегии. На графиках Flamy AI уровень SL рассчитывается моделью на основе исторической волатильности инструмента.

-

Take Profit: когда забирать прибыль

-

Take Profit — целевой уровень закрытия позиции с прибылью. TP рассчитывается пропорционально прогнозному движению с учётом Risk:Reward ratio.

-

Risk:Reward Ratio

-

Оптимальное соотношение риска к доходности — не менее 1:2. Это означает, что потенциальная прибыль должна минимум вдвое превышать риск.

-
    -
  • SL: не более 1% от капитала на сделку
  • -
  • TP: 2% и выше от точки входа
  • -
  • Одна сделка: не более 2% депозита
  • -
-

Почему это важно при работе с ML-прогнозами

-

ML-модель не даёт гарантий. Уверенность 80% означает, что 20% прогнозов будут неточными. Управление рисками — страховка на эти 20%.

- ` + content: [ + { + type: 'paragraph', + text: 'Управление рисками — фундамент любой торговой стратегии. Без него даже точный ML-прогноз не поможет сохранить капитал.' + }, + { type: 'heading', text: 'Stop Loss: где ваша позиция неправа' }, + { + type: 'paragraph', + text: 'Stop Loss — уровень, при достижении которого позиция закрывается автоматически. Это не признание ошибки, а часть стратегии. На графиках Flamy AI уровень SL рассчитывается моделью на основе исторической волатильности инструмента.' + }, + { type: 'heading', text: 'Take Profit: когда забирать прибыль' }, + { + type: 'paragraph', + text: 'Take Profit — целевой уровень закрытия позиции с прибылью. TP рассчитывается пропорционально прогнозному движению с учётом Risk:Reward ratio.' + }, + { type: 'heading', text: 'Risk:Reward Ratio' }, + { + type: 'paragraph', + text: 'Оптимальное соотношение риска к доходности — не менее 1:2. Это означает, что потенциальная прибыль должна минимум вдвое превышать риск.' + }, + { + type: 'list', + items: [ + 'SL: не более 1% от капитала на сделку', + 'TP: 2% и выше от точки входа', + 'Одна сделка: не более 2% депозита' + ] + }, + { type: 'heading', text: 'Почему это важно при работе с ML-прогнозами' }, + { + type: 'paragraph', + text: 'ML-модель не даёт гарантий. Уверенность 80% означает, что 20% прогнозов будут неточными. Управление рисками — страховка на эти 20%.' + } + ] }, { id: 2, slug: 'kak-chitat-grafiki-flamy-ai', date: '2026-05-17', title: 'Как читать графики Flamy AI', - description: - 'Краткое объяснение свечей, прогнозной зоны, TP и SL на графиках Flamy AI.', + description: 'Краткое объяснение свечей, прогнозной зоны, TP и SL на графиках Flamy AI.', tags: ['ML', 'FORECAST', 'CHARTS'], - content: ` -

Графики Flamy AI содержат три слоя: исторические свечи, прогнозную зону и уровни торгового плана. Разберём каждый из них.

-

Исторические свечи

-

Левая часть графика — реальные OHLC-свечи. Зелёные — бычьи (close > open), красные — медвежьи. Это основа для анализа модели.

-

Прогнозная зона

-

Правая часть — прогнозные свечи на горизонт 19 периодов вперёд. Это не точные значения, а вероятностный коридор движения цены на ближайшие 95 минут.

-

Уровни Entry, TP и SL

-

Если модель публикует режим TRADE_PLAN, на графике появляются три горизонтальные линии:

-
    -
  • Entry — рекомендуемый уровень входа в позицию
  • -
  • TP — цель Take Profit
  • -
  • SL — Stop Loss для ограничения убытков
  • -
-

Таймфрейм и горизонт

-

Все графики работают на таймфрейме 5 минут. Горизонт прогноза — 19 свечей = 95 минут вперёд. Прогнозы обновляются каждый час автоматически.

- ` + content: [ + { + type: 'paragraph', + text: 'Графики Flamy AI содержат три слоя: исторические свечи, прогнозную зону и уровни торгового плана. Разберём каждый из них.' + }, + { type: 'heading', text: 'Исторические свечи' }, + { + type: 'paragraph', + text: 'Левая часть графика — реальные OHLC-свечи. Зелёные — бычьи, красные — медвежьи. Это основа для анализа модели.' + }, + { type: 'heading', text: 'Прогнозная зона' }, + { + type: 'paragraph', + text: 'Правая часть — прогнозные свечи на горизонт 19 периодов вперёд. Это не точные значения, а вероятностный коридор движения цены на ближайшие 95 минут.' + }, + { type: 'heading', text: 'Уровни Entry, TP и SL' }, + { + type: 'paragraph', + text: 'Если модель публикует режим TRADE_PLAN, на графике появляются три горизонтальные линии.' + }, + { + type: 'list', + items: [ + 'Entry — рекомендуемый уровень входа в позицию', + 'TP — цель Take Profit', + 'SL — Stop Loss для ограничения убытков' + ] + }, + { type: 'heading', text: 'Таймфрейм и горизонт' }, + { + type: 'paragraph', + text: 'Все графики работают на таймфрейме 5 минут. Горизонт прогноза — 19 свечей = 95 минут вперёд. Прогнозы обновляются каждый час автоматически.' + } + ] } ]; export function getPostBySlug(slug: string): Post | undefined { return posts.find((p) => p.slug === slug); -} \ No newline at end of file +} diff --git a/src/lib/components/Chart.svelte b/src/lib/components/Chart.svelte index 7ff514e..27fd733 100644 --- a/src/lib/components/Chart.svelte +++ b/src/lib/components/Chart.svelte @@ -9,7 +9,7 @@ type IChartApi, type ISeriesApi, type MouseEventParams, - type UTCTimestamp, + type UTCTimestamp } from 'lightweight-charts'; import type { ChartData, CandleBar } from '$lib/stores/chartStore'; @@ -50,7 +50,7 @@ high: 0, low: 0, close: 0, - isUp: true, + isUp: true }); function fmt(n: number): string { @@ -75,7 +75,7 @@ lineWidth: 1, lineStyle: LineStyle.Solid, axisLabelVisible: true, - title: 'Entry', + title: 'Entry' }), candleSeries.createPriceLine({ price: d.signal.tp, @@ -83,7 +83,7 @@ lineWidth: 1, lineStyle: LineStyle.Dashed, axisLabelVisible: true, - title: 'TP', + title: 'TP' }), candleSeries.createPriceLine({ price: d.signal.sl, @@ -91,8 +91,8 @@ lineWidth: 1, lineStyle: LineStyle.Dashed, axisLabelVisible: true, - title: 'SL', - }), + title: 'SL' + }) ]; chart.timeScale().fitContent(); @@ -107,11 +107,11 @@ textColor: '#8a887f', fontFamily: "'JetBrains Mono', monospace", fontSize: 11, - attributionLogo: false, + attributionLogo: false }, grid: { vertLines: { color: '#1a191e' }, - horzLines: { color: '#1a191e' }, + horzLines: { color: '#1a191e' } }, crosshair: { mode: CrosshairMode.Normal, @@ -119,25 +119,25 @@ color: '#3d3b42', labelBackgroundColor: '#1a191e', style: LineStyle.Dashed, - width: 1, + width: 1 }, horzLine: { color: '#3d3b42', labelBackgroundColor: '#1a191e', style: LineStyle.Dashed, - width: 1, - }, + width: 1 + } }, rightPriceScale: { borderColor: '#1a191e', - scaleMargins: { top: 0.06, bottom: 0.04 }, + scaleMargins: { top: 0.06, bottom: 0.04 } }, timeScale: { borderColor: '#1a191e', timeVisible: true, secondsVisible: false, - rightOffset: 24, - }, + rightOffset: 24 + } }); candleSeries = chart.addSeries(CandlestickSeries, { @@ -146,7 +146,7 @@ borderUpColor: '#26a69a', borderDownColor: '#ef5350', wickUpColor: '#26a69a', - wickDownColor: '#ef5350', + wickDownColor: '#ef5350' }); predSeries = chart.addSeries(LineSeries, { @@ -158,7 +158,7 @@ crosshairMarkerBorderColor: '#fe4b07', crosshairMarkerBackgroundColor: '#09080a', priceLineVisible: false, - lastValueVisible: true, + lastValueVisible: true }); applyData(data); @@ -169,17 +169,22 @@ return; } const c = param.seriesData.get(candleSeries) as CandleBar; - if (!c) { tip = { ...tip, visible: false }; return; } + if (!c) { + tip = { ...tip, visible: false }; + return; + } - const pred = predSeries && param.seriesData.has(predSeries) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ? (param.seriesData.get(predSeries) as any)?.value - : undefined; + const pred = + predSeries && param.seriesData.has(predSeries) + ? (param.seriesData.get(predSeries) as { value?: number })?.value + : undefined; const ts = param.time as number; const d = new Date(ts * 1000); - const timeStr = d.toLocaleDateString('ru-RU', { day: '2-digit', month: 'short' }) - + ' ' + d.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' }); + const timeStr = + d.toLocaleDateString('ru-RU', { day: '2-digit', month: 'short' }) + + ' ' + + d.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' }); tip = { visible: true, @@ -191,14 +196,14 @@ low: c.low, close: c.close, isUp: c.close >= c.open, - pred, + pred }; }); const ro = new ResizeObserver(() => { chart?.applyOptions({ width: container.clientWidth, - height: container.clientHeight, + height: container.clientHeight }); }); ro.observe(container); @@ -229,7 +234,7 @@ style="left: {left}px; top: {top}px" >

{tip.time}

- {#each [['O', tip.open], ['H', tip.high], ['L', tip.low], ['C', tip.close]] as [lbl, val]} + {#each [['O', tip.open], ['H', tip.high], ['L', tip.low], ['C', tip.close]] as [lbl, val] (lbl)}
{lbl} {fmt(val as number)} @@ -237,7 +242,7 @@ {/each} {#if tip.pred !== undefined}
- ML + ML {fmt(tip.pred)}
{/if} diff --git a/src/lib/components/home/DashboardMockup.svelte b/src/lib/components/home/DashboardMockup.svelte index 7e9d9e8..dbcf7ce 100644 --- a/src/lib/components/home/DashboardMockup.svelte +++ b/src/lib/components/home/DashboardMockup.svelte @@ -62,7 +62,7 @@ } -
+
-