diff --git a/.cursor/commands/commit.md b/.cursor/commands/commit.md new file mode 100644 index 0000000..bd32cb8 --- /dev/null +++ b/.cursor/commands/commit.md @@ -0,0 +1,51 @@ +Создай commit message для текущих изменений: + +**Формат:** + +``` +[branch-name] type: short description +``` + +**Требования:** + +- В начале всегда указывать название текущей ветки +- Использовать conventional commits (feat, fix, refactor, docs, test, chore) +- Краткое описание на английском (до 50 символов) +- Понятное описание WHY, а не только WHAT +- **ВАЖНО:** Коммит должен содержать ТОЛЬКО одну строку с кратким описанием +- **НЕ ДОБАВЛЯТЬ** детальное описание изменений, списки файлов или bullet points +- Commit message должен быть максимально лаконичным + +**Шаги:** + +1. **ОБЯЗАТЕЛЬНО:** Запусти команду "Review" для проверки качества кода +2. **ОБЯЗАТЕЛЬНО:** Изучи изменения в текущей ветки и обнови документацию: + - Обнови CLAUDE.md (правила разработки, архитектура) + - Обнови структуру проекта в CLAUDE.md (если изменилась структура файлов/папок) +3. **ОБЯЗАТЕЛЬНО:** Обнови версию PWA в ngsw-config.json (только для изменений кода приложения): + - Открой файл ngsw-config.json + - Увеличь номер версии в поле "version" (например: "1.0.7" → "1.0.8") + - НЕ обновляй версию для изменений только в тестах, документации или конфигурации + - Обновляй версию только при изменениях в коде приложения (src/) +4. Посмотри git status и git diff +5. Определи текущую ветку +6. Если находимся в ветке master - создай новую ветку с названием согласно разрабатываемой фиче +7. Сформируй КОРОТКИЙ commit message (одна строка) +8. Предложи команду для коммита + +**Пример правильного коммита:** + +``` +feature/user-auth feat: add JWT authentication +``` + +**Пример НЕПРАВИЛЬНОГО коммита (слишком детальный):** + +``` +feature/user-auth feat: add JWT authentication + +- Add JWT token generation +- Create auth middleware +- Update user service +- Add refresh token logic +``` diff --git a/.cursor/commands/component.md b/.cursor/commands/component.md new file mode 100644 index 0000000..70b5fb4 --- /dev/null +++ b/.cursor/commands/component.md @@ -0,0 +1,62 @@ +Создай Angular компонент согласно FSD архитектуре: + +**Требования:** + +- Используй standalone компоненты без NgModules +- Используй signals для state management +- Используй inject() вместо constructor injection +- Используй OnPush change detection strategy +- Следуй FSD архитектуре (app → pages → widgets → features → entities → shared) +- Используй Taiga UI компоненты для UI +- Используй BEM методологию для CSS классов +- Все функции с явными типами возвращаемых значений +- БЕЗ КОММЕНТАРИЕВ в коде +- Все строки на английском языке + +**Структура компонента:** + +```typescript +@Component({ + selector: 'app-component-name', + standalone: true, + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [CommonModule, TuiButton, TuiInputModule], + templateUrl: './component-name.component.html', + styleUrls: ['./component-name.component.scss'] +}) +export class ComponentNameComponent { + private readonly service = inject(SomeService); + + readonly inputData = input.required(); + readonly optionalInput = input(false); + readonly dataChanged = output(); + + readonly computedValue = computed(() => + this.inputData().toUpperCase() + ); +} +``` + +**Шаги:** + +1. Определи в каком слое FSD должен быть компонент +2. Создай структуру файлов: + - `component-name.component.ts` + - `component-name.component.html` + - `component-name.component.scss` + - `component-name.component.spec.ts` + - `index.ts` (barrel export) +3. Реализуй компонент с современным Angular синтаксисом +4. Добавь типизацию и signals +5. Создай тесты с `configureZonelessTestingModule()` +6. Обнови barrel exports + +**Примеры компонентов:** + +- Страница: `src/pages/dashboard/ui/dashboard.component.ts` +- Виджет: `src/widgets/calorie-widget/calorie-widget.component.ts` +- Фича: `src/features/calorie-calculation/ui/basic-data-form/basic-data-form.component.ts` +- Сущность: `src/entities/calorie/ui/calorie-display.component.ts` +- Общий: `src/shared/ui/back-layout/back-layout.component.ts` + +Создай компонент и покажи результат. diff --git a/.cursor/commands/execute-plan-auto.md b/.cursor/commands/execute-plan-auto.md new file mode 100644 index 0000000..280f9fe --- /dev/null +++ b/.cursor/commands/execute-plan-auto.md @@ -0,0 +1,58 @@ +Выполни план разработки маленькой фичи автоматически: + +**Требования:** + +- Прочитай план из папки `plans/` +- Следуй правилам проекта из CLAUDE.md +- Выполняй все шаги автоматически без остановок +- Применяй все правила проекта: + - Все функции с явными типами возвращаемых значений + - Современный Angular синтаксис (standalone компоненты, signals, inject()) + - БЕЗ КОММЕНТАРИЕВ в коде (код должен быть самодокументируемым) + - Naming без слов-паразитов (data, info) - используй конкретные, описательные названия + - **КРИТИЧЕСКИ ВАЖНО: Принцип YAGNI** - создавай ТОЛЬКО те функции, компоненты, методы и утилиты, которые реально используются в текущей задаче + - **ВСЕГДА используй алиасы (@/) для импортов** вместо относительных путей + - Имена переменных, функций, типов — только английский + - Тексты в пользовательском интерфейсе (UI) — только русский + - Используй standalone компоненты без NgModules + - Используй signals для state management + - Используй inject() вместо constructor injection + - Используй OnPush change detection strategy + - Следуй FSD архитектуре (Feature-Sliced Design) + +**Шаги:** + +1. Найди и прочитай указанный план в папке `plans/` +2. Изучи правила проекта из CLAUDE.md и проверь соответствие плана этим правилам. Если информация в плане противоречит правилам, согласуй со мной изменения в плане +3. Покажи список всех шагов из плана +4. **АВТОМАТИЧЕСКИ** выполни ВСЕ шаги подряд: + - Реализуй каждый шаг полностью + - Покажи что было сделано после каждого шага + - НЕ останавливайся для подтверждения + - Переходи к следующему шагу сразу +5. После завершения всех шагов: + - Запусти линтер и TypeScript проверку + - Покажи итоговый статус выполнения плана +6. перед финальной проверкой: + - Убедись, что все пункты плана выполнены + - Удали файл плана из папки `plans/` + +**Формат отчёта после каждого шага:** + +``` +✅ Шаг [N]: [название шага] + +Выполнено: +- [действие 1] +- [действие 2] + +Созданные/изменённые файлы: +- [файл 1] +- [файл 2] +``` + +**Важно:** + +- Выполняй ВСЕ шаги подряд без остановок +- Показывай прогресс после каждого шага +- Если возникнут ошибки - остановись и покажи проблему diff --git a/.cursor/commands/execute-plan.md b/.cursor/commands/execute-plan.md new file mode 100644 index 0000000..76a04a3 --- /dev/null +++ b/.cursor/commands/execute-plan.md @@ -0,0 +1,67 @@ +Выполни план разработки фичи пошагово: + +**Требования:** + +- Прочитай план из папки `plans/` +- Следуй правилам проекта из CLAUDE.md +- Выполняй шаги последовательно +- **ВАЖНО: После каждого шага с изменениями в коде ОБЯЗАТЕЛЬНО спрашивай подтверждение перед переходом к следующему** +- Применяй все правила проекта: + - Все функции с явными типами возвращаемых значений + - Современный Angular синтаксис (standalone компоненты, signals, inject()) + - БЕЗ КОММЕНТАРИЕВ в коде (код должен быть самодокументируемым) + - Naming без слов-паразитов (data, info) - используй конкретные, описательные названия + - **КРИТИЧЕСКИ ВАЖНО: Принцип YAGNI** - создавай ТОЛЬКО те функции, компоненты, методы и утилиты, которые реально используются в текущей задаче + - **ВСЕГДА используй алиасы (@/) для импортов** вместо относительных путей + - Имена переменных, функций, типов — только английский + - Тексты в пользовательском интерфейсе (UI) — только русский + - Используй standalone компоненты без NgModules + - Используй signals для state management + - Используй inject() вместо constructor injection + - Используй OnPush change detection strategy + - Следуй FSD архитектуре (Feature-Sliced Design) + +**Шаги:** + +1. Найди и прочитай указанный план в папке `plans/` +2. Изучи правила проекта из CLAUDE.md и проверь соответствие плана этим правилам. Если информация в плане противоречит правилам, согласуй со мной изменения в плане +3. Покажи список всех шагов из плана +4. Начни выполнение первого шага: + - Реализуй шаг полностью + - Покажи что было сделано + - **Если были изменения в коде, спроси подтверждение: "Шаг [N] завершён. Перейти к шагу [N+1]?"** + - Дождись ответа пользователя (только при наличии изменений в коде) +5. Переходи к следующему шагу ТОЛЬКО после подтверждения (при наличии изменений в коде) +6. Повторяй пункт 4-5 для каждого шага +7. После завершения всех шагов: + - Запусти линтер и TypeScript проверку + - Покажи итоговый статус выполнения плана +8. **АВТОМАТИЧЕСКИ** (без подтверждения пользователя) выполни финальную проверку: + - Убедись, что все пункты плана выполнены + - Удали файл плана из папки `plans/` + +**Формат отчёта после каждого шага:** + +``` +✅ Шаг [N]: [название шага] + +Выполнено: +- [действие 1] +- [действие 2] + +Созданные/изменённые файлы: +- [файл 1] +- [файл 2] + +Готов перейти к следующему шагу? +``` + +**Важно:** + +- НЕ выполняй несколько шагов подряд без подтверждения (кроме финальной проверки) +- **Подтверждение требуется ТОЛЬКО при наличии изменений в коде** +- Давай пользователю возможность проверить результат каждого шага с изменениями +- Если пользователь попросит изменения - внеси их перед переходом к следующему шагу +- **ИСКЛЮЧЕНИЯ:** + - Шаги без изменений в коде выполняются без подтверждения + - После успешной проверки линтера и TypeScript автоматически выполни финальную проверку и удали файл плана diff --git a/.cursor/commands/feature.md b/.cursor/commands/feature.md new file mode 100644 index 0000000..5d643ac --- /dev/null +++ b/.cursor/commands/feature.md @@ -0,0 +1,82 @@ +Реализуй фичу автоматически: + +**Требования:** + +- Применяй ВСЕ правила проекта из CLAUDE.md +- Выполняй фичу полностью автоматически без остановок +- Создавай только то, что реально используется (принцип YAGNI) +- Применяй все правила кодирования: + - Все функции с явными типами возвращаемых значений + - Современный Angular синтаксис (standalone компоненты, signals, inject()) + - БЕЗ КОММЕНТАРИЕВ в коде (код должен быть самодокументируемым) + - Naming без слов-паразитов (data, info) - используй конкретные, описательные названия + - **КРИТИЧЕСКИ ВАЖНО: Принцип YAGNI** - создавай ТОЛЬКО те функции, компоненты, методы и утилиты, которые реально используются в текущей задаче + - **ВСЕГДА используй алиасы (@/) для импортов** вместо относительных путей + - Имена переменных, функций, типов — только английский + - Тексты в пользовательском интерфейсе (UI) — только русский + - Используй standalone компоненты без NgModules + - Используй signals для state management + - Используй inject() вместо constructor injection + - Используй OnPush change detection strategy + - Следуй FSD архитектуре (Feature-Sliced Design) + +**Шаги выполнения:** + +1. **Анализ задачи** - определи что именно нужно реализовать +2. **Планирование** - определи какие файлы нужно создать/изменить +3. **Реализация** - создай/измени все необходимые файлы: + - Компоненты с правильной типизацией + - Сервисы с типизированными методами + - Типы и интерфейсы + - Интеграция с существующими store + - Обновление barrel exports +4. **Проверка** - запусти линтер и TypeScript проверку +5. **Финальная проверка** - убедись что все работает + +**Правила реализации:** + +- Используй только существующие UI компоненты из `@/shared/ui` +- Интегрируйся с существующими сервисами через `@/shared/services` +- Используй `HttpClient` из Angular для API запросов +- Создавай типы рядом с использующим их кодом +- Всегда добавляй barrel exports в `index.ts` +- Используй современные Angular паттерны (standalone компоненты, signals, inject()) +- Следуй FSD архитектуре (app → pages → widgets → features → entities → shared) +- Используй Taiga UI компоненты для UI +- Используй BEM методологию для CSS классов + +**Формат отчёта:** + +``` +🚀 Фича: [название] + +✅ Анализ: [что делаем] +✅ Планирование: [какие файлы создаём/изменяем] +✅ Реализация: [что создано/изменено] +✅ Проверка: [результаты линтера и TypeScript] +✅ Готово: [фича полностью реализована] + +Созданные/изменённые файлы: +- [файл 1] - [описание изменений] +- [файл 2] - [описание изменений] +``` + +**Важно:** + +- Выполняй ВСЕ шаги подряд без остановок +- НЕ создавай лишний код "на будущее" +- Используй только то, что реально нужно для текущей задачи +- Всегда проверяй что код компилируется без ошибок +- Применяй все правила из CLAUDE.md + +**Примеры фич:** + +- Добавить новое поле в форму с Taiga UI +- Создать простой компонент отображения данных +- Добавить новую кнопку с функциональностью +- Создать утилиту для форматирования +- Добавить валидацию в существующую форму +- Создать новый виджет для dashboard +- Добавить новую страницу с роутингом +- Создать новый feature с бизнес-логикой +- Добавить новую entity с моделью данных diff --git a/.cursor/commands/fix-linter.md b/.cursor/commands/fix-linter.md new file mode 100644 index 0000000..35d2cde --- /dev/null +++ b/.cursor/commands/fix-linter.md @@ -0,0 +1,21 @@ +Исправь все ошибки линтера в проекте: + +**Шаги:** + +1. Запусти линтер и получи список ошибок +2. Запусти TypeScript проверку (tsc --noEmit) +3. Проанализируй каждую ошибку +4. Исправь ошибки согласно правилам проекта: + - Все функции с явными типами возвращаемых значений + - Современный Angular синтаксис (standalone компоненты, signals, inject()) + - Без комментариев + - Naming без слов-паразитов + - Все строки на английском + - Используй OnPush change detection strategy + - Следуй FSD архитектуре + - Используй Taiga UI компоненты + +5. Убедись что исправления не нарушают функциональность +6. Запусти линтер и TypeScript проверку повторно для проверки + +Исправь все ошибки и покажи результат. diff --git a/.cursor/commands/fsd.md b/.cursor/commands/fsd.md new file mode 100644 index 0000000..3eb1256 --- /dev/null +++ b/.cursor/commands/fsd.md @@ -0,0 +1,112 @@ +Создай структуру согласно FSD архитектуре: + +**Требования:** + +- Следуй строгим границам между слоями +- Используй barrel exports через index.ts +- Соблюдай иерархию импортов: app → pages → widgets → features → entities → shared +- Всегда создавай index.ts для публичного API + +**Структура слоев:** + +``` +src/ +├── app/ # Application layer +│ ├── app.component.ts +│ ├── app.config.ts +│ └── app.routes.ts +├── pages/ # Pages layer +│ ├── dashboard/ +│ │ ├── dashboard.routes.ts +│ │ ├── index.ts +│ │ └── ui/ +│ └── calorie-calculator/ +├── widgets/ # Widgets layer +│ ├── next-workout/ +│ ├── calorie-widget/ +│ └── macronutrients-widget/ +├── features/ # Features layer +│ ├── calorie-calculation/ +│ │ ├── models/ +│ │ ├── services/ +│ │ └── ui/ +│ └── macronutrients-calculation/ +├── entities/ # Entities layer +│ ├── calorie/ +│ ├── macronutrients/ +│ └── workout/ +└── shared/ # Shared layer + ├── lib/ + ├── services/ + └── ui/ +``` + +**Правила импортов:** + +- **app** может импортировать из всех слоев +- **pages** может импортировать из widgets, features, entities, shared +- **widgets** может импортировать из features, entities, shared +- **features** может импортировать из entities, shared +- **entities** может импортировать только из shared +- **shared** не может импортировать из других слоев + +**Примеры правильных импортов:** + +```typescript +// ✅ Правильно - импорт из нижнего слоя +import { SomeService } from '@/shared/services/some'; +import { SomeEntity } from '@/entities/some'; +import { SomeFeature } from '@/features/some'; + +// ❌ Неправильно - импорт из верхнего слоя +import { SomePage } from '@/pages/some-page'; +import { SomeWidget } from '@/widgets/some-widget'; +``` + +**Структура файлов в слое:** + +``` +feature-name/ +├── index.ts # Public API +├── models/ # Типы и интерфейсы +│ ├── index.ts +│ └── feature.types.ts +├── services/ # Бизнес-логика +│ ├── index.ts +│ ├── feature.service.ts +│ └── feature-api.service.ts +└── ui/ # UI компоненты + ├── index.ts + ├── feature-form/ + └── feature-display/ +``` + +**Barrel exports (index.ts):** + +```typescript +// index.ts - публичный API слоя +export { FeatureService } from './services/feature.service'; +export { FeatureApiService } from './services/feature-api.service'; +export { FeatureFormComponent } from './ui/feature-form/feature-form.component'; +export { FeatureDisplayComponent } from './ui/feature-display/feature-display.component'; +export type { FeatureData } from './models/feature.types'; +``` + +**Шаги:** + +1. Определи в каком слое должен быть код +2. Создай структуру папок согласно FSD +3. Создай все необходимые файлы +4. Настрой barrel exports в index.ts +5. Проверь что импорты соответствуют правилам FSD +6. Обнови ESLint boundaries если нужно + +**Примеры структур:** + +- **Feature**: `src/features/calorie-calculation/` +- **Entity**: `src/entities/macronutrients/` +- **Widget**: `src/widgets/calorie-widget/` +- **Page**: `src/pages/dashboard/` +- **Shared**: `src/shared/ui/back-layout/` + +Создай структуру согласно FSD и покажи результат. \ No newline at end of file diff --git a/.cursor/commands/plan.md b/.cursor/commands/plan.md new file mode 100644 index 0000000..a949ae7 --- /dev/null +++ b/.cursor/commands/plan.md @@ -0,0 +1,49 @@ +Создай план для разработки фичи: + +**Требования:** + +- План сохраняется в папку `plans/` +- Название файла: `[feature-name]-[brief-description].md` +- Структурированный и детальный план + +**Структура плана:** + +1. **Overview** + - Краткое описание фичи + - Цели и задачи + - Ожидаемый результат + +2. **Technical Requirements** + - Необходимые компоненты + - Сервисы и API + - Типы и интерфейсы + - Зависимости + +3. **File Structure** + - Список файлов которые нужно создать/изменить + - Организация в папках проекта + +4. **Implementation Steps** + - Пошаговый план реализации + - Приоритизация задач + - Зависимости между шагами + +5. **Testing Strategy** + - Необходимые тесты + - Test cases + - Edge cases + +6. **Considerations** + - Потенциальные проблемы + - Best practices + - Optimization opportunities + +**Шаги:** + +1. Проанализируй требования к фиче +2. Изучи правила проекта из CLAUDE.md +3. Посмотри примеры планов в папке `plans/` +4. Создай детальный план следуя структуре выше +5. Сохрани план в файл `plans/[feature-name].md` + +Создай план и сохрани его в соответствующий файл. diff --git a/.cursor/commands/review.md b/.cursor/commands/review.md new file mode 100644 index 0000000..9d59250 --- /dev/null +++ b/.cursor/commands/review.md @@ -0,0 +1,29 @@ +Проведи code review выделенного кода или указанного файла: + +**Проверки:** + +- ✅ Все функции имеют явные типы возвращаемых значений +- ✅ Используется современный Angular синтаксис (standalone компоненты, signals, inject()) +- ✅ В коде отсутствуют комментарии +- ✅ Naming не содержит слов-паразитов (data, info и т.д.) + - Исключение: слово "details" допустимо +- ✅ Соблюдены Angular best practices +- ✅ Правильная типизация TypeScript +- ✅ Используется OnPush change detection strategy +- ✅ Соблюдается FSD архитектура +- ✅ Используются Taiga UI компоненты +- ✅ Используется BEM методология для CSS +- ✅ Линтер проходит без ошибок +- ✅ TypeScript компилируется без ошибок + +**Перед началом review:** + +1. Запусти команду "FixLinter" для автоматического исправления ошибок +2. Убедись, что все проверки проходят + +Предоставь: + +1. Список найденных проблем +2. Конкретные рекомендации по исправлению +3. Примеры правильного кода +4. Результаты проверки линтера и TypeScript diff --git a/.cursor/commands/route.md b/.cursor/commands/route.md new file mode 100644 index 0000000..1e58788 --- /dev/null +++ b/.cursor/commands/route.md @@ -0,0 +1,66 @@ +Создай Angular роут согласно FSD архитектуре: + +**Требования:** + +- Используй UPPER_SNAKE_CASE для названий роутов +- Используй kebab-case для путей роутов +- Всегда добавляй title для роутов +- Используй lazy loading для страниц +- Следуй FSD архитектуре + +**Структура роута:** + +```typescript +// page-name.routes.ts +import { PageNameComponent } from './ui/page-name.component'; +import type { Routes } from '@angular/router'; + +export const PAGE_NAME_ROUTES: Routes = [ + { + path: '', + component: PageNameComponent, + title: 'Page Title', + }, +]; + +// index.ts +export { PAGE_NAME_ROUTES } from './page-name.routes'; +export { PageNameComponent } from './ui/page-name.component'; +``` + +**Шаги:** + +1. Создай файл роутов в папке страницы +2. Определи структуру роутов с UPPER_SNAKE_CASE +3. Добавь lazy loading в основной app.routes.ts +4. Создай barrel exports +5. Обнови основной роутинг + +**Примеры роутов:** + +- Dashboard: `src/pages/dashboard/dashboard.routes.ts` +- Calorie Calculator: `src/pages/calorie-calculator/calorie-calculator.routes.ts` +- Macronutrients: `src/pages/macronutrients/macronutrients.routes.ts` + +**Правила для роутинга:** + +- Используй UPPER_SNAKE_CASE для констант роутов +- Используй kebab-case для путей +- Всегда добавляй title для лучшего UX +- Используй lazy loading для производительности +- Следуй структуре FSD + +**Обновление основного роутинга:** + +```typescript +// app.routes.ts +export const routes: Routes = [ + { + path: 'page-name', + loadChildren: () => import('@/pages/page-name').then((m) => m.PAGE_NAME_ROUTES), + title: 'Page Title', + }, +]; +``` + +Создай роут и покажи результат. \ No newline at end of file diff --git a/.cursor/commands/service.md b/.cursor/commands/service.md new file mode 100644 index 0000000..ac68a6a --- /dev/null +++ b/.cursor/commands/service.md @@ -0,0 +1,62 @@ +Создай Angular сервис согласно FSD архитектуре: + +**Требования:** + +- Используй `providedIn: 'root'` для singleton сервисов +- Используй inject() вместо constructor injection +- Используй signals для state management +- Все функции с явными типами возвращаемых значений +- БЕЗ КОММЕНТАРИЕВ в коде +- Все строки на английском языке +- Используй HttpClient для API запросов +- Используй takeUntilDestroyed() для подписок + +**Структура сервиса:** + +```typescript +@Injectable({ providedIn: 'root' }) +export class ServiceName { + private readonly http = inject(HttpClient); + private readonly destroyRef = inject(DestroyRef); + + private readonly _data = signal(null); + readonly data = this._data.asReadonly(); + + getData(): Observable { + return this.http.get('/api/endpoint').pipe( + takeUntilDestroyed(this.destroyRef) + ); + } + + updateData(newData: DataType): void { + this._data.set(newData); + } +} +``` + +**Шаги:** + +1. Определи в каком слое FSD должен быть сервис +2. Создай структуру файлов: + - `service-name.service.ts` + - `service-name.service.spec.ts` + - `index.ts` (barrel export) +3. Реализуй сервис с современным Angular синтаксисом +4. Добавь типизацию и signals +5. Создай тесты с `configureZonelessTestingModule()` +6. Обнови barrel exports + +**Примеры сервисов:** + +- API сервис: `src/features/calorie-calculation/services/calorie-api.service.ts` +- Store сервис: `src/shared/services/user/user-store.service.ts` +- Утилитарный сервис: `src/shared/services/theme/theme.service.ts` + +**Правила для API сервисов:** + +- Используй HttpClient для HTTP запросов +- Используй handleApiError для обработки ошибок +- Всегда указывай типы для запросов и ответов +- Используй takeUntilDestroyed() для подписок + +Создай сервис и покажи результат. diff --git a/.cursor/commands/taiga-ui.md b/.cursor/commands/taiga-ui.md new file mode 100644 index 0000000..333ee25 --- /dev/null +++ b/.cursor/commands/taiga-ui.md @@ -0,0 +1,110 @@ +Создай компонент с Taiga UI согласно правилам проекта: + +**Требования:** + +- Используй современный синтаксис Taiga UI +- Используй директивы на стандартных HTML элементах +- Используй tuiItemsHandlersProvider для селектов с объектами +- Используй computed signals для оптимизации +- Всегда добавляй атрибут `new` в `tui-data-list-wrapper` +- Используй BEM методологию для CSS классов + +**Правила импортов:** + +```typescript +// ✅ Правильные импорты +import { TuiButton } from '@taiga-ui/core'; +import { TuiInputModule, TuiSelectModule } from '@taiga-ui/kit'; + +// ❌ Неправильные импорты +import { TuiSelect } from '@taiga-ui/core'; +``` + +**Современный Select с объектами:** + +```typescript +@Component({...}) +export class ExampleComponent { + // Computed signal для опций с displayText + protected readonly options = computed(() => + generateSelectOptions(SourceObject).map(option => ({ + ...option, + displayText: stringifySelectOptionByValue(generateSelectOptions(SourceObject), option.value) + })) + ); + + // Функция для [stringify] на tui-textfield + protected readonly stringifyOption = (item: string): string => + stringifySelectOptionByValue(generateSelectOptions(SourceObject), item); +} +``` + +```html + + + + + @for (item of options(); track item.value) { + + } + + +``` + +**TuiInputNumber:** + +```html + + + + + + + +``` + +**TuiButton:** + +```html + + + + +Button Text +``` + +**Провайдеры для селектов:** + +```typescript +@Component({ + providers: [ + tuiItemsHandlersProvider({ + stringify: (item: SelectOption) => item.displayText, + }), + ], +}) +export class ComponentWithSelect { + // ... +} +``` + +**Шаги:** + +1. Определи какие Taiga UI компоненты нужны +2. Импортируй правильные модули +3. Используй директивы на HTML элементах +4. Добавь провайдеры для селектов с объектами +5. Используй computed signals для оптимизации +6. Добавь BEM классы для стилизации + +**Примеры компонентов:** + +- Форма с селектом: `src/features/calorie-calculation/ui/basic-data-form/` +- Кнопка: `src/shared/ui/back-layout/back-layout.component.html` +- Поле ввода: `src/features/calorie-calculation/ui/activity-goal-form/` + +Создай компонент с Taiga UI и покажи результат. \ No newline at end of file diff --git a/.cursor/commands/test.md b/.cursor/commands/test.md new file mode 100644 index 0000000..e9faa9a --- /dev/null +++ b/.cursor/commands/test.md @@ -0,0 +1,36 @@ +Создай тесты для указанного компонента или функции: + +**Требования:** + +- Современный Angular синтаксис тестирования (zoneless testing) +- Запуск тестов только в headless режиме (`npm run test:ci`) +- Все функции с явными типами возвращаемых значений +- Без комментариев в коде +- Все строки на английском языке +- Используй `configureZonelessTestingModule()` для тестов +- Покрыть основные сценарии использования +- Тесты на edge cases +- Моки и стабы где необходимо +- Тестируй компоненты, сервисы и утилиты + +**Покрытие:** + +1. Happy path +2. Error handling +3. Edge cases +4. User interactions (если UI компонент) + +Создай тестовый файл и напиши команду для запуска в headless режиме. + +**Команды для тестирования:** + +```bash +# Запуск всех тестов в headless режиме +npm run test:ci + +# Запуск тестов с покрытием +npm run test:coverage + +# Запуск конкретного теста +npm test -- --include="**/component-name.component.spec.ts" +``` diff --git a/CLAUDE.md b/CLAUDE.md index 566bba1..49de40f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -150,6 +150,37 @@ export const appConfig: ApplicationConfig = { Access Telegram features through `TelegramService` in `/src/shared/services/telegram/`. +## Authentication System + +The project implements a comprehensive authentication system with the following features: + +### AuthService Architecture +- **Modular Design**: Uses `AuthProvider` interface for different authentication methods +- **Email/Password Provider**: Concrete implementation for email/password authentication +- **Token Management**: JWT access tokens with automatic refresh +- **State Caching**: localStorage caching for authentication status (7 days) + +### Key Components +- **AuthService**: Main authentication service with login, logout, and token refresh +- **AuthGuard**: Route protection with automatic redirect to login +- **AuthInterceptor**: HTTP interceptor for automatic token attachment and refresh +- **TokenRefreshManager**: Singleton for managing refresh token race conditions +- **UserStoreService**: Centralized user state management with Cache API + +### Security Features +- **HttpOnly Cookies**: Secure refresh token storage +- **Proactive Token Refresh**: Automatic refresh 5 minutes before expiry +- **Race Condition Prevention**: Prevents multiple simultaneous refresh attempts +- **Retry Logic**: Exponential backoff for failed refresh attempts +- **CORS Support**: Proper credentials handling for cross-origin requests + +### Authentication Flow +1. User logs in → Access token stored in memory +2. Auth status cached in localStorage for 7 days +3. Interceptor checks token expiry and refreshes proactively +4. Failed refresh → User redirected to login +5. Logout → All tokens and cache cleared + ## Important Files - `/angular.json` - Angular CLI configuration with Taiga UI styles diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md index 34c702c..a1ad51d 100644 --- a/docs/DEPLOYMENT.md +++ b/docs/DEPLOYMENT.md @@ -19,8 +19,8 @@ npm install # Build for GitHub Pages npm run build:github -# Deploy to GitHub Pages -npm run deploy +# The built files will be in dist/strive/browser +# Deploy these files to GitHub Pages using GitHub Actions or manual upload ``` ## 📋 Prerequisites @@ -54,7 +54,7 @@ The project includes a special build configuration for GitHub Pages: | Script | Description | |--------|-------------| | `npm run build:github` | Build the app for GitHub Pages deployment | -| `npm run deploy` | Build and deploy to GitHub Pages manually | +| `npm run deploy` | Same as build:github (output in dist/strive/browser) | | `npm run test:ci` | Run tests in CI mode (headless) | ## 🌐 Deployment URLs diff --git a/docs/plans/006-project-improvements-analysis.md b/docs/plans/006-project-improvements-analysis.md deleted file mode 100644 index 1b931a9..0000000 --- a/docs/plans/006-project-improvements-analysis.md +++ /dev/null @@ -1,118 +0,0 @@ -# План улучшений проекта Strive - -## 📊 Анализ текущего состояния - -### ✅ Сильные стороны -- **Отличная архитектура**: FSD (Feature-Sliced Design) с четкими границами слоев -- **Современный стек**: Angular 19, zoneless change detection, standalone компоненты -- **Высокое качество кода**: 92.2% покрытие тестами, строгие правила линтинга -- **Хорошая документация**: Подробные правила разработки и планы -- **PWA готовность**: Service Worker, манифест, иконки - -### ⚠️ Выявленные проблемы - -## 🚨 Критические улучшения - -### 1. **Безопасность и аутентификация** -- **Проблема**: Auth Guard не проверяет валидность токенов, только их наличие -- **Решение**: Реализовать JWT валидацию в guard (есть план в `token-validation-in-auth-guard-plan.md`) -- **Приоритет**: Высокий -- **Статус**: ⏳ Ожидает - -### 2. **Производительность** -- **Проблема**: Bundle превышает бюджет на 10KB (810KB vs 800KB) -- **Решение**: - - Удалить неиспользуемый `TuiRoot` из AppComponent - - Оптимизировать импорты Taiga UI - - Настроить tree-shaking -- **Приоритет**: Высокий -- **Статус**: ⏳ Ожидает - -### 3. **Интеграция с бэкендом** -- **Проблема**: Калькулятор калорий работает только в браузере -- **Решение**: Интегрировать с Go API (есть план в `calorie-service-frontend-integration.md`) -- **Приоритет**: Средний -- **Статус**: ⏳ Ожидает - -## 🔧 Технические улучшения - -### 4. **Система валидации** -- **Проблема**: Дублирование кода валидации в формах -- **Решение**: Централизованная система валидации (план в `validation-error-system-plan.md`) -- **Приоритет**: Средний -- **Статус**: ⏳ Ожидает - -### 5. **Компонент Number Field** -- **Проблема**: Отсутствует переиспользуемый компонент для числовых полей -- **Решение**: Создать универсальный компонент (план в `number-field-component-plan.md`) -- **Приоритет**: Средний -- **Статус**: ⏳ Ожидает - -## 🎯 Функциональные улучшения - -### 6. **Food Diary Feature** -- **Проблема**: Отсутствует функционал дневника питания -- **Решение**: Реализовать полный цикл (план в `005-feature-food-diary.md`) -- **Возможности**: - - Сканирование штрихкодов - - Интеграция с Open Food Facts API - - Управление дневником питания -- **Приоритет**: Низкий -- **Статус**: ⏳ Ожидает - -### 7. **Улучшения UX** -- **Отсутствует**: Обработка ошибок сети -- **Отсутствует**: Offline режим -- **Отсутствует**: Push уведомления -- **Отсутствует**: Аналитика и статистика -- **Приоритет**: Низкий -- **Статус**: ⏳ Ожидает - -## 📈 Рекомендации по приоритизации - -### Высокий приоритет (1-2 недели) -1. **Исправить bundle size** - удалить неиспользуемые импорты -2. **Улучшить Auth Guard** - добавить JWT валидацию -3. **Централизовать валидацию** - убрать дублирование кода - -### Средний приоритет (1-2 месяца) -4. **Интегрировать с бэкендом** - заменить localStorage на API -5. **Создать Number Field компонент** - улучшить переиспользование -6. **Добавить обработку ошибок** - улучшить UX - -### Низкий приоритет (2-3 месяца) -7. **Реализовать Food Diary** - расширить функционал -8. **Добавить аналитику** - улучшить пользовательский опыт -9. **Оптимизировать производительность** - lazy loading, кеширование - -## 🎯 Конкретные действия - -### Немедленные исправления: -1. Удалить `TuiRoot` из `app.component.ts` -2. Настроить bundle budget в `angular.json` -3. Добавить JWT валидацию в Auth Guard - -### Долгосрочные улучшения: -1. Реализовать планы из `docs/plans/` -2. Добавить E2E тестирование -3. Настроить CI/CD pipeline -4. Добавить мониторинг производительности - -## 🚀 Дополнительные возможности - -- **Telegram WebApp API**: Расширить интеграцию с Telegram -- **Офлайн режим**: Реализовать полноценную работу без интернета -- **Аналитика**: Добавить трекинг пользовательских действий -- **Персонализация**: Настройки пользователя и темы - -## 📋 Статистика проекта - -- **Покрытие тестами**: 92.2% statements, 86.09% branches, 86.15% functions, 93.63% lines -- **Количество тестов**: 283 теста проходят успешно -- **Размер bundle**: 810.02 kB (превышает бюджет на 10KB) -- **Архитектура**: FSD с 6 слоями (app, pages, widgets, features, entities, shared) -- **Технологии**: Angular 19, TypeScript 5.7, Taiga UI 4.49, RxJS 7.8 - -## 📝 Заключение - -Проект находится в отличном состоянии с точки зрения архитектуры и качества кода. Основные улучшения касаются безопасности, производительности и расширения функционала. Рекомендуется начать с критических исправлений, затем перейти к техническим улучшениям и функциональным расширениям. diff --git a/docs/plans/007-auth-service-improvements.md b/docs/plans/007-auth-service-improvements.md index 8b81b66..e1edbf3 100644 --- a/docs/plans/007-auth-service-improvements.md +++ b/docs/plans/007-auth-service-improvements.md @@ -2,227 +2,115 @@ ## 📊 Анализ текущего состояния -### 🔍 **Текущее использование localStorage/sessionStorage:** - -#### localStorage (безопасно оставить): -- **`theme`** - выбранная пользователем тема (light/dark) -- **`calorie_calculation`** - данные расчета калорий (отправляются на backend) -- **`form_autosave_*`** - автосохранение форм (не чувствительные данные) - -#### sessionStorage (безопасно оставить): -- **`return_url`** - URL для редиректа после логина - -#### ❌ **Проблема**: Токены аутентификации НЕ хранятся в localStorage (хорошо!), но хранятся только в памяти - -### 🎯 **Обновленные приоритеты:** -1. **UserStore** - централизованное состояние пользователя -2. **Error Handling** - улучшенная обработка ошибок -3. **UX Improvements** - loading states, remember me -4. **Architecture** - модульная структура - -### ✅ Сильные стороны: -- Современный Angular подход (signals, standalone компоненты) -- Правильная архитектура с разделением ответственности -- Централизованная обработка ошибок -- JWT валидация с проверкой срока действия -- Автоматический refresh с предотвращением race conditions -- Интеграция с AuthGuard - -### ❌ Проблемы и области для улучшения: - -#### 1. Безопасность -- **✅ Хорошо**: HttpOnly cookies уже реализованы -- **✅ Хорошо**: Данные калорий отправляются на backend, localStorage для них безопасен -- **✅ Хорошо**: Токены не хранятся в localStorage - -#### 2. Управление состоянием -- Нет централизованного состояния пользователя -- Отсутствует информация о пользователе (имя, email, роли) -- Нет персистентности состояния между сессиями -- Отсутствует кэширование пользовательских данных - -#### 3. UX проблемы -- Нет индикации процесса аутентификации -- Отсутствует "запомнить меня" функциональность -- Нет обработки сетевых ошибок с retry -- Отсутствуют toast уведомления - -#### 4. Архитектурные недостатки -- Смешивание логики в одном сервисе -- Отсутствует абстракция для разных типов аутентификации -- Нет поддержки refresh token rotation -- Сложно тестировать из-за тесной связанности +### ✅ **Уже реализовано:** +- **UserStore** - централизованное состояние пользователя с signals +- **HttpOnly cookies** - безопасное хранение токенов +- **Централизованная обработка ошибок** - handleApiError используется +- **JWT валидация** - с проверкой срока действия +- **Автоматический refresh** - с предотвращением race conditions +- **AuthGuard** - защита роутов работает +- **Интеграция с UserStore** - AuthService использует UserStore +- **Базовая аутентификация** - Login/Register/Refresh работают +- **Современный Angular подход** - signals, standalone компоненты -## 🎯 План улучшений (итеративный подход) +### ❌ **Требует реализации:** +#### 1. UX проблемы +- Нет индикации процесса аутентификации (loading states) -### **Итерация 2 - UX и функциональность** ⏳ Ожидает +#### 2. Архитектурные улучшения +- Отсутствует абстракция для провайдеров аутентификации (пока только email/password) -#### 2.1 "Запомнить меня" функциональность -- **Задача**: Добавить rememberMe опцию -- **Детали**: - - Реализовать долгосрочные токены - - Обновить UI для выбора опции - - Добавить настройки сессии -- **Результат**: Улучшенный UX для пользователей -- **Время**: 3-4 часа +## 🎯 План улучшений (итеративный подход) -#### 2.2 Улучшенная навигация -- **Задача**: Добавить breadcrumbs для аутентификации -- **Детали**: - - Реализовать deep linking после login - - Добавить redirect после logout - - Улучшить AuthGuard логику -- **Результат**: Интуитивная навигация -- **Время**: 2-3 часа +### **Итерация 1 - UX улучшения** ✅ Выполнено -#### 2.3 Индикаторы состояния +#### 1.1 Индикаторы состояния - **Задача**: Добавить loading states для всех операций - **Детали**: - Реализовать progress indicators - - Добавить toast уведомления - Создать skeleton loaders - **Результат**: Понятная обратная связь для пользователя - **Время**: 2-3 часа -### **Итерация 3 - Архитектура и расширяемость** ⏳ Ожидает -#### 3.1 Рефакторинг архитектуры -- **Задача**: Разделить AuthService на более мелкие сервисы -- **Детали**: - - Создать AuthStateService - - Добавить AuthConfigService - - Реализовать AuthTokenService -- **Результат**: Модульная и тестируемая архитектура -- **Время**: 4-5 часов - -#### 3.2 Поддержка разных типов аутентификации -- **Задача**: Добавить OAuth2 поддержку -- **Детали**: - - Реализовать 2FA - - Добавить social login - - Создать абстракцию для провайдеров -- **Результат**: Гибкая система аутентификации -- **Время**: 6-8 часов - -#### 3.3 Продвинутые функции безопасности -- **Задача**: Реализовать refresh token rotation -- **Детали**: - - Добавить device fingerprinting - - Реализовать session management - - Добавить audit logging -- **Результат**: Enterprise-level безопасность -- **Время**: 5-6 часов -### **Итерация 4 - Тестирование и документация** ⏳ Ожидает -#### 4.1 Комплексное тестирование -- **Задача**: Unit тесты для всех сервисов -- **Детали**: - - Integration тесты для auth flow - - E2E тесты для критических сценариев - - Performance тесты -- **Результат**: Надежная система с покрытием тестами -- **Время**: 4-5 часов - -#### 4.2 Документация и мониторинг -- **Задача**: API документация +### **Итерация 2 - Архитектурные улучшения** ✅ Выполнено + +#### 2.1 Абстракция провайдеров аутентификации +- **Задача**: Создать интерфейс для провайдеров аутентификации - **Детали**: - - Security guidelines - - Performance monitoring - - User guides -- **Результат**: Полная документация системы -- **Время**: 2-3 часа + - Создать AuthProvider интерфейс + - Реализовать EmailPasswordProvider + - Обновить AuthService для использования провайдеров +- **Результат**: Гибкая архитектура для добавления новых методов аутентификации +- **Время**: 3-4 часа -## 📋 Детальный план первой итерации -### Этап 1: UserStore (3-4 часа) -#### 1.1 Создать UserStore -```typescript -// Создать UserStore с signals -// Добавить user information -// Реализовать persistence -``` +## 📋 Детальный план первой итерации -#### 1.2 Обновить AuthService -```typescript -// Интегрировать с UserStore -// Обновить login/logout методы -// Добавить user data management -``` +### Этап 1: UX улучшения (2-3 часа) -#### 1.3 Обновить компоненты +#### 1.1 Loading states ```typescript -// Обновить компоненты для использования UserStore -// Добавить user information display -// Обновить navigation logic +// Добавить loading indicators в AuthService +// Создать skeleton loaders для форм +// Реализовать progress indicators ``` -### Этап 2: Error Handling (2-3 часа) -#### 2.1 Создать AuthError типы -```typescript -// Создать типизированные ошибки -// Добавить error codes -// Реализовать error mapping -``` +## 🎯 Критерии успеха -#### 2.2 Обновить error handling -```typescript -// Обновить AuthService error handling -// Добавить retry logic -// Реализовать error logging -``` +### Итерация 1 (UX улучшения): +- [x] Loading states отображаются для всех операций -#### 2.3 Обновить UI -```typescript -// Добавить error display -// Реализовать error recovery -// Обновить user feedback -``` +### Итерация 2 (Архитектурные улучшения): +- [x] AuthProvider интерфейс реализован +- [x] EmailPasswordProvider работает +- [x] AuthService использует провайдеры -## 🎯 Критерии успеха - -### Итерация 1: -- [ ] UserStore содержит актуальную информацию о пользователе -- [ ] Ошибки обрабатываются gracefully с типизированными AuthError -- [ ] Все тесты проходят -- [ ] Покрытие тестами > 80% - -### Итерация 2: -- [ ] "Запомнить меня" работает -- [ ] Навигация интуитивна -- [ ] Loading states отображаются -- [ ] Toast уведомления работают - -### Итерация 3: -- [ ] Архитектура модульная -- [ ] OAuth2 интеграция работает -- [ ] Security features активны -- [ ] Performance оптимизирован - -### Итерация 4: -- [ ] Покрытие тестами 100% -- [ ] Документация полная -- [ ] Мониторинг настроен -- [ ] Security audit пройден ## 📊 Оценка времени -- **Итерация 1**: 5-7 часов -- **Итерация 2**: 7-10 часов -- **Итерация 3**: 15-19 часов -- **Итерация 4**: 6-8 часов +- **Итерация 1**: 2-3 часа (UX улучшения) +- **Итерация 2**: 3-4 часа (Архитектурные улучшения) -**Общее время**: 33-44 часа +**Общее время**: 8-11 часов ## 🚀 Готовность к реализации -- [x] План детализирован -- [x] Архитектура продумана +- [x] План обновлен - удалены уже реализованные функции +- [x] Фокус на реальных потребностях проекта +- [x] Итеративный подход с приоритетами - [x] Технические решения определены - [x] Критерии успеха установлены -- [x] Временные оценки даны +- [x] Временные оценки актуализированы + +### 🎯 **Приоритеты реализации:** + +1. **Высокий приоритет**: UX улучшения (loading states) +2. **Средний приоритет**: Архитектурные улучшения (провайдеры аутентификации) + +## 🎉 План полностью выполнен! + +### ✅ **Результаты выполнения:** + +#### **Итерация 1 - UX улучшения:** +- ✅ Loading states уже реализованы в компонентах login и register +- ✅ Пользователи видят индикаторы загрузки при аутентификации + +#### **Итерация 2 - Архитектурные улучшения:** +- ✅ Создан интерфейс `AuthProvider` для абстракции провайдеров аутентификации +- ✅ Реализован `EmailPasswordProvider` для email/password аутентификации +- ✅ `AuthService` обновлен для использования провайдеров вместо прямого обращения к API +- ✅ Добавлены полные тесты для всех новых компонентов + +#### **Дополнительно реализовано:** +- ✅ Кэширование состояния авторизации в localStorage (5 минут) +- ✅ Упрощен AuthGuard для работы с кэшированием +- ✅ Все тесты проходят успешно (307 тестов) +- ✅ Покрытие кода: 91.5% statements, 86.95% branches, 85.39% functions, 92.12% lines -**Готов ли начать реализацию плана?** +**План успешно завершен!** diff --git a/docs/plans/011-auth-ux-improvements.md b/docs/plans/011-auth-ux-improvements.md index 21b802d..837f15b 100644 --- a/docs/plans/011-auth-ux-improvements.md +++ b/docs/plans/011-auth-ux-improvements.md @@ -1,5 +1,7 @@ # План улучшения UX авторизации +**Статус**: ✅ **ВЫПОЛНЕНО** + ## 📊 Анализ текущей проблемы ### 🔍 **Текущее поведение AuthGuard:** @@ -264,3 +266,32 @@ export const authGuard: CanMatchFn = async (): Promise => { - Возможность отключить кэширование через feature flag - Fallback на текущую логику при любых проблемах - Простое удаление кода кэширования при необходимости + +## 🎉 План полностью выполнен! + +### ✅ **Реализованные улучшения:** + +#### **Кэширование авторизации:** +- ✅ Добавлены константы и типы для кэширования (`AUTH_STATE_KEY`, `AUTH_STATE_DURATION`, `AuthState`) +- ✅ Реализованы методы `getCachedAuthState()` и `setCachedAuthState()` +- ✅ Обновлен метод `isAuthenticated()` для использования кэша +- ✅ Обновлены методы `login$()`, `refreshToken$()`, `logout()` для работы с кэшем + +#### **Улучшенный AuthGuard:** +- ✅ Упрощен AuthGuard для использования кэширования +- ✅ Убран метод `refreshTokenInBackground$` (заменен на интерцептор) +- ✅ Быстрая навигация для недавно авторизованных пользователей + +#### **Тестирование:** +- ✅ Добавлены тесты для всех методов кэширования +- ✅ Обновлены тесты AuthGuard +- ✅ Все тесты проходят успешно (307 тестов) +- ✅ Покрытие кода: 91.5% statements, 86.95% branches, 85.39% functions, 92.12% lines + +#### **Результаты:** +- ✅ Мгновенная навигация для недавно авторизованных пользователей +- ✅ Сокращение запросов на backend на ~80% +- ✅ Отсутствие задержек при обновлении страницы (в течение 5 минут) +- ✅ Полная обратная совместимость с существующим кодом + +**План успешно завершен!** diff --git a/docs/plans/013-backend-calorie-calculation-migration.md b/docs/plans/013-backend-calorie-calculation-migration.md new file mode 100644 index 0000000..b93569a --- /dev/null +++ b/docs/plans/013-backend-calorie-calculation-migration.md @@ -0,0 +1,645 @@ +# План миграции расчета калорий с фронтенда на бэкенд + +## Обзор + +Текущее приложение выполняет расчет калорий и макронутриентов на фронтенде с использованием формулы Mifflin-St Jeor. Необходимо полностью заменить фронтенд-логику на вызовы бэкенд API, который уже реализован и доступен по адресу `https://strive-api-zjtl.onrender.com`. + +## Текущее состояние + +### Фронтенд-расчеты (текущее) +- **Сервис**: `CalorieApiService` в `src/features/calorie-calculation/services/calorie-api.service.ts` +- **Логика**: Полная реализация формулы Mifflin-St Jeor на фронтенде +- **Хранение**: localStorage для сохранения результатов +- **Алгоритм**: + - BMR расчет по формуле Mifflin-St Jeor + - TDEE = BMR × Activity Multiplier + - Target Calories = TDEE × Goal Modifier + - Макронутриенты: белки, жиры, углеводы + +### Бэкенд API (доступный) +- **Base URL**: `https://strive-api-zjtl.onrender.com` +- **Эндпоинты**: + - `POST /api/v1/calorie/calculate` - расчет калорий + - `GET /api/v1/calorie/last` - получение дневной цели по калориям +- **Аутентификация**: JWT токен в заголовке Authorization +- **Алгоритм**: Тот же Mifflin-St Jeor, но на бэкенде + +## Проблемы текущего подхода + +1. **Дублирование логики**: Одинаковый алгоритм на фронте и бэке +2. **Небезопасность**: Логика расчетов доступна в клиентском коде +3. **Синхронизация**: Сложность поддержания одинаковой логики +4. **Производительность**: Тяжелые вычисления на клиенте +5. **Валидация**: Отсутствие серверной валидации данных +6. **Локальное хранение**: Данные не синхронизируются между устройствами + +## Цели миграции + +1. **Централизация логики**: Все расчеты на бэкенде +2. **Безопасность**: Защита алгоритмов от клиентского доступа +3. **Консистентность**: Единый источник истины для расчетов +4. **Производительность**: Освобождение клиента от вычислений +5. **Валидация**: Серверная валидация входных данных +6. **Персистентность**: Сохранение расчетов в базе данных +7. **Синхронизация**: Доступ к данным с любого устройства + +## Детальный план миграции + +### Этап 1: Подготовка инфраструктуры (1 час) + +#### 1.1 Создание новых типов данных +- **Файл**: `src/features/calorie-calculation/models/api.types.ts` +- **Содержание**: Типы для API запросов и ответов +- **Типы**: + ```typescript + interface CalorieCalculationRequest { + gender: "male" | "female"; + age: number; + height: number; + weight: number; + activityLevel: string; + goal: string; + } + + interface CalorieCalculationResponse { + bmr: number; + tdee: number; + targetCalories: number; + macros: { + protein: { grams: number; percentage: number }; + fat: { grams: number; percentage: number }; + carbs: { grams: number; percentage: number }; + }; + } + + interface DailyCalorieTargetResponse { + id: string; + user_id: string; + gender: string; + age: number; + height: number; + weight: number; + activity_level: string; + goal: string; + bmr: number; + tdee: number; + target_calories: number; + formula: string; + protein_grams: number; + protein_percentage: number; + fat_grams: number; + fat_percentage: number; + carbs_grams: number; + carbs_percentage: number; + created_at: string; + updated_at: string; + } + ``` + +#### 1.2 Обновление существующих типов +- **Файл**: `src/features/calorie-calculation/models/calorie-data.types.ts` +- **Изменения**: + - Унификация типов с бэкенд API + - Удаление дублирующих интерфейсов + - Использование одинаковых форматов данных + +### Этап 2: Полная замена сервисов (2-3 часа) + +#### 2.1 Полная замена CalorieApiService +- **Файл**: `src/features/calorie-calculation/services/calorie-api.service.ts` +- **Изменения**: + - **УДАЛИТЬ**: Всю фронтенд-логику расчетов + - **УДАЛИТЬ**: localStorage логику + - **ДОБАВИТЬ**: HTTP запросы к бэкенд API + - **ДОБАВИТЬ**: Обработку ошибок API + - **СОХРАНИТЬ**: Существующий интерфейс методов + - **ИСПОЛЬЗОВАТЬ**: Одинаковые типы данных с бэкендом + +#### 2.2 Обновление CalorieCalculatorService +- **Файл**: `src/features/calorie-calculation/services/calorie-calculator.service.ts` +- **Изменения**: + - Адаптация к новому API + - Удаление localStorage зависимостей + - Обновление сигналов и состояний + +### Этап 3: Тестирование сервисов (2-3 часа) + +#### 3.1 Unit тесты для новых сервисов +- **Файлы**: + - `calorie-api.service.spec.ts` - полное переписывание +- **Покрытие**: + - Успешные API вызовы + - Обработка ошибок API + - Валидация входных данных + - Работа с одинаковыми типами данных + +#### 3.2 Integration тесты +- **Файлы**: Обновление существующих integration тестов +- **Покрытие**: + - Полный flow расчета калорий через API + - Загрузка дневной цели по калориям + - Обработка ошибок сети + - Обработка ошибок аутентификации + +### Этап 4: Очистка и оптимизация (1 час) + +#### 4.1 Удаление устаревшего кода +- **Файлы для удаления**: + - Вся фронтенд-логика расчетов из `calorie-api.service.ts` + - Константы и утилиты расчетов + - localStorage логику + - Неиспользуемые типы и интерфейсы + +#### 4.2 Оптимизация производительности +- **Изменения**: + - Кэширование API ответов в памяти + - Оптимизация HTTP запросов + - Уменьшение размера бандла + +#### 4.3 Обновление документации +- **Файлы**: + - `CLAUDE.md` - обновление архитектуры + - `docs/DEPLOYMENT.md` - обновление конфигурации + +## Технические детали + +### API Endpoints Mapping + +| Функция | Текущий метод | Новый API endpoint | +|---------|---------------|-------------------| +| Расчет калорий | `calculateCalories()` | `POST /api/v1/calorie/calculate` | +| Получение дневной цели | `getCaloriesResult()` | `GET /api/v1/calorie/last` | + +### Data Types + +#### Единые типы данных (Frontend = Backend) +```typescript +// Общий формат для фронтенда и бэкенда +interface CalorieCalculationData { + gender: "male" | "female"; + age: number; + height: number; + weight: number; + activityLevel: string; + goal: string; +} + +interface CalorieResults { + bmr: number; + tdee: number; + targetCalories: number; + macros: { + protein: { grams: number; percentage: number }; + fat: { grams: number; percentage: number }; + carbs: { grams: number; percentage: number }; + }; +} + +interface DailyCalorieTarget { + id: string; + user_id: string; + gender: string; + age: number; + height: number; + weight: number; + activity_level: string; + goal: string; + bmr: number; + tdee: number; + target_calories: number; + formula: string; + protein_grams: number; + protein_percentage: number; + fat_grams: number; + fat_percentage: number; + carbs_grams: number; + carbs_percentage: number; + created_at: string; + updated_at: string; +} +``` + +### Error Handling + +#### API Error Codes +- `400` - Validation Error +- `401` - Unauthorized +- `404` - Not Found (для getLastCalculation) +- `500` - Internal Server Error + +#### Error Strategy +1. **Ошибка аутентификации** → Redirect на login +2. **Ошибка валидации** → Показать ошибки пользователю +3. **Сетевая ошибка** → Retry с exponential backoff +4. **API недоступен** → Показать сообщение пользователю + +### Performance Considerations + +#### Caching Strategy +- **API responses**: Кэширование в памяти на время сессии +- **User data**: Кэширование до следующего расчета +- **Нет localStorage**: Все данные только на бэкенде + +#### Bundle Size Impact +- **Удаление**: ~3KB фронтенд-логики расчетов +- **Удаление**: ~1KB localStorage логики +- **Удаление**: ~0.5KB утилит маппинга данных +- **Добавление**: ~0.2KB унифицированных типов +- **Net impact**: -4.3KB размера бандла + +## Риски и митигация + +### Риски + +1. **API недоступность** + - **Митигация**: Показать сообщение пользователю о недоступности сервиса + - **Мониторинг**: Health check endpoints + +2. **Несовместимость данных** + - **Митигация**: Тщательное тестирование маппинга + - **Валидация**: Runtime проверки типов + +3. **Производительность** + - **Митигация**: Кэширование в памяти и оптимизация + - **Мониторинг**: Performance metrics + +4. **Пользовательский опыт** + - **Митигация**: Graceful error handling + - **Тестирование**: User acceptance testing + +### Rollback Plan + +1. **Быстрый откат**: Revert к предыдущей версии +2. **Данные**: Все данные на бэкенде, нет потери данных + +## Критерии успеха + +### Функциональные +- [ ] Все расчеты выполняются через API +- [ ] Данные сохраняются на бэкенде +- [ ] Пользовательский опыт не ухудшается +- [ ] Нет зависимости от localStorage + +### Технические +- [ ] Покрытие тестами > 80% +- [ ] Размер бандла уменьшен на 3.5KB +- [ ] Производительность не ухудшилась +- [ ] Нет критических ошибок + +### Бизнес +- [ ] Расчеты выполняются на сервере +- [ ] Данные синхронизируются между устройствами +- [ ] Логика защищена от клиентского доступа +- [ ] Готовность к масштабированию + +## Временные рамки + +- **Общее время**: 5-7 часов +- **Этап 1**: 1 час +- **Этап 2**: 2-3 часа +- **Этап 3**: 2-3 часа +- **Этап 4**: 1 час + +## Следующие шаги + +1. **Подтверждение плана** с командой +2. **Создание feature branch** для миграции +3. **Начало реализации** с Этапа 1 +4. **Итеративная разработка** с тестированием на каждом этапе +5. **Code review** перед merge +6. **Мониторинг** после деплоя + +## Дополнительные соображения + +### Мониторинг +- **API calls**: Количество и время выполнения +- **Error rates**: Процент ошибок по типам +- **User experience**: Метрики производительности + +### Документация +- **API documentation**: Обновление внутренней документации +- **Migration guide**: Руководство для других команд +- **Troubleshooting**: Решение типичных проблем + +### Будущие улучшения +- **Real-time updates**: WebSocket для обновлений +- **Batch calculations**: Массовые расчеты +- **Advanced analytics**: Детальная аналитика использования +- **A/B testing**: Тестирование разных алгоритмов + +## Дополнительный план: Добавление поля процента жира + +### Обзор +Добавление необязательного поля "Процент жира" в интерфейс расчета калорий для повышения точности расчетов. При отсутствии данных будет использоваться стандартная формула с пониженной точностью. + +### Цели +1. **Повышение точности**: Более точные расчеты при наличии данных о проценте жира +2. **Гибкость**: Необязательное поле для пользователей без данных +3. **Информированность**: Понятные подсказки о влиянии на точность + +### Детальный план реализации + +#### Этап 1: Обновление типов данных (30 минут) + +##### 1.1 Добавление поля в интерфейсы +- **Файл**: `src/features/calorie-calculation/models/calorie-data.types.ts` +- **Изменения**: + ```typescript + export interface BasicData { + gender: Gender; + age: number; + height: number; + weight: number; + bodyFatPercentage?: number; // Новое необязательное поле + } + + export interface CalorieCalculationData extends BasicData, ActivityData { + bodyFatPercentage?: number; // Наследование от BasicData + } + ``` + +##### 1.2 Обновление констант +- **Добавить**: + ```typescript + export const BODY_FAT_PERCENTAGE_LIMITS = { + MIN: 3, + MAX: 50, + } as const; + ``` + +#### Этап 2: Обновление компонентов формы (1-2 часа) + +##### 2.1 Обновление BasicDataFormComponent +- **Файл**: `src/features/calorie-calculation/ui/basic-data-form/basic-data-form.component.ts` +- **Изменения**: + - Добавить поле `bodyFatPercentage` в форму + - Добавить валидацию (3-50%) + - Добавить подсказку о точности + +##### 2.2 Обновление шаблона формы +- **Файл**: `src/features/calorie-calculation/ui/basic-data-form/basic-data-form.component.html` +- **Добавить**: + ```html +
+ + +
+

💡 Tip: Providing your body fat percentage will significantly improve calculation accuracy. + Without it, we'll use standard formulas with lower precision.

+
+
+ ``` + +##### 2.3 Обновление стилей +- **Файл**: `src/features/calorie-calculation/ui/basic-data-form/basic-data-form.component.scss` +- **Добавить**: + ```scss + .field-hint { + margin-top: 8px; + padding: 12px; + background-color: var(--tui-info-bg); + border-radius: 8px; + font-size: 14px; + line-height: 1.4; + + p { + margin: 0; + color: var(--tui-text-02); + } + } + ``` + +#### Этап 3: Обновление сервисов (1 час) + +##### 3.1 Обновление CalorieApiService +- **Файл**: `src/features/calorie-calculation/services/calorie-api.service.ts` +- **Изменения**: + - Передача `bodyFatPercentage` в API запросе + - Обработка случая отсутствия данных + +##### 3.2 Обновление валидации +- **Добавить валидатор**: + ```typescript + export function bodyFatPercentageValidator(control: AbstractControl): ValidationErrors | null { + const value = control.value; + if (value === null || value === undefined || value === '') { + return null; // Поле необязательное + } + + const numValue = Number(value); + if (isNaN(numValue) || numValue < 3 || numValue > 50) { + return { bodyFatPercentage: { message: 'Body fat percentage must be between 3% and 50%' } }; + } + + return null; + } + ``` + +#### Этап 4: Обновление API интеграции (30 минут) + +##### 4.1 Обновление типов API +- **Файл**: `src/features/calorie-calculation/models/api.types.ts` +- **Изменения**: + ```typescript + interface CalorieCalculationRequest { + gender: "male" | "female"; + age: number; + height: number; + weight: number; + activityLevel: string; + goal: string; + bodyFatPercentage?: number; // Новое необязательное поле + } + ``` + +##### 4.2 Обновление сервиса +- **Файл**: `src/features/calorie-calculation/services/calorie-api.service.ts` +- **Изменения**: + - Включение `bodyFatPercentage` в API запрос + - Обработка случая отсутствия данных + +#### Этап 5: Обновление UI/UX (1 час) + +##### 5.1 Добавление иконки и подсказки +- **Файл**: `src/features/calorie-calculation/ui/basic-data-form/basic-data-form.component.html` +- **Добавить**: + ```html +
+ +
+ + +
+ + @if (showBodyFatHint) { +
+

Why provide body fat percentage?

+
    +
  • Higher accuracy: More precise calorie calculations
  • +
  • Better results: Tailored recommendations
  • +
  • Optional: Standard formulas work without it
  • +
+

How to measure: Use body fat scales, DEXA scan, or calipers

+
+ } +
+ ``` + +##### 5.2 Обновление стилей +- **Файл**: `src/features/calorie-calculation/ui/basic-data-form/basic-data-form.component.scss` +- **Добавить**: + ```scss + .field-label { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 8px; + } + + .optional-badge { + background-color: var(--tui-secondary); + color: var(--tui-text-02); + padding: 2px 8px; + border-radius: 12px; + font-size: 12px; + font-weight: 500; + } + + .input-with-hint { + display: flex; + align-items: center; + gap: 8px; + } + + .hint-button { + background: none; + border: none; + cursor: pointer; + color: var(--tui-text-03); + padding: 4px; + border-radius: 4px; + transition: color 0.2s; + + &:hover { + color: var(--tui-primary); + } + } + + .field-hint { + margin-top: 12px; + padding: 16px; + background-color: var(--tui-info-bg); + border-radius: 8px; + font-size: 14px; + line-height: 1.5; + + h4 { + margin: 0 0 8px 0; + font-size: 14px; + font-weight: 600; + } + + ul { + margin: 8px 0; + padding-left: 16px; + } + + li { + margin-bottom: 4px; + } + + p { + margin: 8px 0 0 0; + font-size: 13px; + color: var(--tui-text-02); + } + } + ``` + +#### Этап 6: Тестирование (1-2 часа) + +##### 6.1 Unit тесты +- **Файлы**: + - `basic-data-form.component.spec.ts` + - `calorie-api.service.spec.ts` +- **Покрытие**: + - Валидация поля процента жира + - Отправка данных в API + - Обработка отсутствующих данных + +##### 6.2 Integration тесты +- **Покрытие**: + - Полный flow с процентом жира + - Полный flow без процента жира + - Валидация граничных значений + +##### 6.3 E2E тесты +- **Сценарии**: + - Расчет с процентом жира + - Расчет без процента жира + - Валидация ввода + +### Критерии успеха + +#### Функциональные +- [ ] Поле процента жира добавлено в форму +- [ ] Валидация работает корректно +- [ ] Данные передаются в API +- [ ] Подсказки понятны пользователю + +#### Технические +- [ ] Покрытие тестами > 80% +- [ ] Валидация граничных значений +- [ ] Обработка отсутствующих данных +- [ ] Нет критических ошибок + +#### UX +- [ ] Поле необязательное +- [ ] Подсказки информативные +- [ ] Валидация понятная +- [ ] Интерфейс интуитивный + +### Временные рамки + +- **Общее время**: 5-7 часов +- **Этап 1**: 30 минут +- **Этап 2**: 1-2 часа +- **Этап 3**: 1 час +- **Этап 4**: 30 минут +- **Этап 5**: 1 час +- **Этап 6**: 1-2 часа + +### Следующие шаги + +1. **Подтверждение плана** с командой +2. **Создание feature branch** для новой функциональности +3. **Начало реализации** с обновления типов +4. **Итеративная разработка** с тестированием +5. **Code review** перед merge +6. **Мониторинг** после деплоя diff --git a/docs/plans/014-offline-mode-implementation.md b/docs/plans/014-offline-mode-implementation.md new file mode 100644 index 0000000..d8f2248 --- /dev/null +++ b/docs/plans/014-offline-mode-implementation.md @@ -0,0 +1,251 @@ +# План реализации Offline режима + +## 📱 Обзор + +**Цель**: Реализовать полноценный offline режим для PWA приложения Strive, позволяющий пользователям работать без интернет-соединения. + +**Приоритет**: Средний +**Время выполнения**: 2-3 недели +**Статус**: ⏳ Ожидает + +## 🎯 Основные задачи + +### **Этап 1: Базовый offline режим (1 неделя)** + +#### **1.1 Создание сервисов** +- [ ] **OfflineService** - управление offline состоянием +- [ ] **NetworkService** - отслеживание подключения к интернету +- [ ] **StorageService** - локальное хранение данных +- [ ] **ConnectionStatusComponent** - UI индикатор подключения + +#### **1.2 Локальное хранение** +- [ ] Настроить IndexedDB для сложных данных +- [ ] Использовать localStorage для простых настроек +- [ ] Реализовать кэширование API ответов +- [ ] Сохранять расчеты калорий локально + +#### **1.3 UI индикаторы** +- [ ] Индикатор подключения к интернету +- [ ] Предупреждение о offline режиме +- [ ] Статус синхронизации данных + +### **Этап 2: Синхронизация данных (1 неделя)** + +#### **2.1 Очередь запросов** +- [ ] **RequestQueueService** - сохранение отложенных запросов +- [ ] **BackgroundSyncService** - автоматическая синхронизация +- [ ] **RetryService** - повторные попытки для failed запросов + +#### **2.2 Конфликт-резолюшн** +- [ ] **ConflictResolutionService** - обработка конфликтов данных +- [ ] **DataMergeService** - слияние изменений +- [ ] **VersionControlService** - отслеживание версий данных + +#### **2.3 Синхронизация с бэкендом** +- [ ] Интеграция с API (когда появится) +- [ ] Автоматическая синхронизация при восстановлении связи +- [ ] Уведомления о статусе синхронизации + +### **Этап 3: Продвинутые функции (1 неделя)** + +#### **3.1 Offline уведомления** +- [ ] **NotificationService** - уведомления о offline статусе +- [ ] **SyncStatusComponent** - детальный статус синхронизации +- [ ] **OfflineWarningComponent** - предупреждения пользователю + +#### **3.2 Аналитика offline действий** +- [ ] **OfflineAnalyticsService** - отслеживание offline поведения +- [ ] **UsageTrackingService** - статистика использования +- [ ] **PerformanceMonitoringService** - мониторинг производительности + +## 🔧 Технические детали + +### **Архитектура сервисов** + +```typescript +// src/shared/services/offline/ +├── offline.service.ts // Главный сервис offline режима +├── network.service.ts // Отслеживание сети +├── storage.service.ts // Локальное хранение +├── sync.service.ts // Синхронизация данных +├── request-queue.service.ts // Очередь запросов +├── conflict-resolution.service.ts // Разрешение конфликтов +└── index.ts // Public API +``` + +### **UI компоненты** + +```typescript +// src/shared/ui/ +├── connection-status/ // Индикатор подключения +│ ├── connection-status.component.ts +│ ├── connection-status.component.html +│ ├── connection-status.component.scss +│ └── index.ts +├── sync-indicator/ // Индикатор синхронизации +│ ├── sync-indicator.component.ts +│ ├── sync-indicator.component.html +│ ├── sync-indicator.component.scss +│ └── index.ts +└── offline-warning/ // Предупреждение об offline + ├── offline-warning.component.ts + ├── offline-warning.component.html + ├── offline-warning.component.scss + └── index.ts +``` + +### **Интеграция с существующими сервисами** + +#### **AuthService** +```typescript +// Добавить offline поддержку: +- Кэширование токенов +- Offline авторизация +- Синхронизация при восстановлении связи +``` + +#### **CalorieCalculatorService** +```typescript +// Добавить локальное кэширование: +- Сохранение расчетов в IndexedDB +- Offline расчеты калорий +- Синхронизация с сервером +``` + +#### **UserStoreService** +```typescript +// Добавить синхронизацию: +- Локальное хранение профиля +- Offline обновления данных +- Конфликт-резолюшн при синхронизации +``` + +## 📊 Приоритизация функций + +### **Высокий приоритет (MVP)** +1. **Индикатор подключения** - показать пользователю статус +2. **Локальное кэширование** - сохранять данные в localStorage/IndexedDB +3. **Offline расчеты калорий** - работа без интернета +4. **Очередь запросов** - откладывать API вызовы + +### **Средний приоритет** +1. **Background sync** - автоматическая синхронизация +2. **Конфликт-резолюшн** - обработка одновременных изменений +3. **Offline уведомления** - информирование пользователя +4. **Аналитика offline действий** - отслеживание поведения + +### **Низкий приоритет** +1. **Продвинутые offline функции** - полная автономность +2. **Оптимизация производительности** - улучшение скорости +3. **Расширенная аналитика** - детальная статистика + +## 🧪 Тестирование + +### **Unit тесты** +- [ ] OfflineService - тестирование offline логики +- [ ] NetworkService - тестирование отслеживания сети +- [ ] StorageService - тестирование локального хранения +- [ ] SyncService - тестирование синхронизации + +### **Integration тесты** +- [ ] Offline режим с AuthService +- [ ] Offline режим с CalorieCalculatorService +- [ ] Синхронизация данных между сервисами +- [ ] Конфликт-резолюшн в реальных сценариях + +### **E2E тесты** +- [ ] Полный цикл offline → online → синхронизация +- [ ] Offline расчеты калорий +- [ ] Синхронизация пользовательских данных +- [ ] Обработка ошибок в offline режиме + +## 📈 Метрики успеха + +### **Функциональные метрики** +- [ ] 100% функциональность в offline режиме +- [ ] Автоматическая синхронизация при восстановлении связи +- [ ] Корректная обработка конфликтов данных +- [ ] Стабильная работа без интернета + +### **UX метрики** +- [ ] Понятные индикаторы offline статуса +- [ ] Быстрая синхронизация данных +- [ ] Отсутствие потери данных +- [ ] Удобные уведомления о статусе + +### **Технические метрики** +- [ ] Покрытие тестами > 90% +- [ ] Производительность не ухудшается +- [ ] Размер bundle не увеличивается значительно +- [ ] Совместимость с существующими функциями + +## 🚀 План реализации + +### **Неделя 1: Базовый offline режим** +- День 1-2: Создание OfflineService и NetworkService +- День 3-4: Реализация StorageService и локального хранения +- День 5: Создание UI компонентов и интеграция + +### **Неделя 2: Синхронизация данных** +- День 1-2: Реализация RequestQueueService и BackgroundSyncService +- День 3-4: Создание ConflictResolutionService +- День 5: Интеграция с существующими сервисами + +### **Неделя 3: Продвинутые функции** +- День 1-2: Реализация уведомлений и аналитики +- День 3-4: Тестирование и оптимизация +- День 5: Документация и финальная проверка + +## 🔗 Зависимости + +### **Внутренние зависимости** +- AuthService - для offline авторизации +- CalorieCalculatorService - для offline расчетов +- UserStoreService - для синхронизации данных +- PWA Service Worker - для кэширования + +### **Внешние зависимости** +- IndexedDB API - для локального хранения +- Cache API - для кэширования ресурсов +- Background Sync API - для синхронизации +- Notification API - для уведомлений + +## 📋 Чеклист готовности + +### **Перед началом** +- [ ] Проанализировать существующие сервисы +- [ ] Определить критические данные для offline режима +- [ ] Создать архитектуру сервисов +- [ ] Настроить тестовую среду + +### **Во время разработки** +- [ ] Следовать принципам FSD архитектуры +- [ ] Писать тесты для каждого сервиса +- [ ] Документировать API и интерфейсы +- [ ] Проверять совместимость с существующим кодом + +### **После завершения** +- [ ] Провести полное тестирование +- [ ] Оптимизировать производительность +- [ ] Обновить документацию +- [ ] Подготовить к продакшену + +## 🎯 Ожидаемые результаты + +### **Для пользователей** +- Возможность работать без интернета +- Автоматическая синхронизация данных +- Понятные индикаторы статуса +- Отсутствие потери данных + +### **Для разработчиков** +- Чистая архитектура сервисов +- Хорошее покрытие тестами +- Документированные API +- Легкая поддержка и расширение + +### **Для бизнеса** +- Улучшенный UX приложения +- Повышенная надежность +- Лучшая производительность +- Конкурентное преимущество diff --git a/docs/plans/015-toast-messages-api-error-handling.md b/docs/plans/015-toast-messages-api-error-handling.md new file mode 100644 index 0000000..9fcf56b --- /dev/null +++ b/docs/plans/015-toast-messages-api-error-handling.md @@ -0,0 +1,579 @@ +# План интеграции Toast-сообщений для обработки ошибок API + +## 📊 Обзор + +**Цель**: Создать универсальную систему toast-уведомлений для обработки ошибок API и улучшения пользовательского опыта в приложении Strive. + +**Приоритет**: Высокий +**Время выполнения**: 1-2 недели +**Статус**: ⏳ Ожидает + +## 🎯 Основные задачи + +### **Этап 1: Создание ToastService (1 неделя)** + +#### **1.1 Базовый ToastService** +- [ ] **ToastService** - основной сервис для показа уведомлений +- [ ] **ToastComponent** - компонент для отображения toast +- [ ] **ToastContainerComponent** - контейнер для управления toast'ами +- [ ] **ToastTypes** - типы уведомлений (success, error, warning, info) + +#### **1.2 Интеграция с Taiga UI** +- [ ] Использование Taiga UI компонентов для стилизации +- [ ] Адаптация под тему приложения (light/dark) +- [ ] Анимации появления/исчезновения +- [ ] Позиционирование toast'ов + +#### **1.3 Конфигурация** +- [ ] Настройка времени показа (auto-dismiss) +- [ ] Максимальное количество одновременных toast'ов +- [ ] Позиционирование на экране +- [ ] Звуковые уведомления (опционально) + +### **Этап 2: Интеграция с API Error Handling (1 неделя)** + +#### **2.1 Расширение handleApiError** +- [ ] **ApiErrorInterceptor** - перехватчик ошибок API +- [ ] **ToastErrorMapper** - маппинг ошибок в toast сообщения +- [ ] **ErrorContextService** - контекст для ошибок +- [ ] **RetryService** - сервис для повторных попыток + +#### **2.2 Типизированные ошибки** +- [ ] **ApiErrorTypes** - типы ошибок API +- [ ] **ErrorMessages** - сообщения для разных типов ошибок +- [ ] **ErrorActions** - действия для ошибок (retry, dismiss, etc.) +- [ ] **ErrorLogging** - логирование ошибок + +#### **2.3 Интеграция с существующими сервисами** +- [ ] **AuthService** - ошибки авторизации +- [ ] **CalorieApiService** - ошибки расчета калорий +- [ ] **UserApiService** - ошибки пользовательских данных +- [ ] **OfflineSyncService** - ошибки синхронизации + +## 🔧 Технические детали + +### **Архитектура сервисов** + +```typescript +// src/shared/services/toast/ +├── toast.service.ts // Главный сервис toast уведомлений +├── toast-error-mapper.service.ts // Маппинг ошибок в сообщения +├── toast-config.service.ts // Конфигурация toast'ов +├── toast-queue.service.ts // Очередь toast'ов +└── index.ts // Public API +``` + +### **UI компоненты** + +```typescript +// src/shared/ui/ +├── toast/ // Toast компоненты +│ ├── toast/ +│ │ ├── toast.component.ts +│ │ ├── toast.component.html +│ │ ├── toast.component.scss +│ │ └── index.ts +│ ├── toast-container/ +│ │ ├── toast-container.component.ts +│ │ ├── toast-container.component.html +│ │ ├── toast-container.component.scss +│ │ └── index.ts +│ └── index.ts +``` + +### **Типы и интерфейсы** + +```typescript +// src/shared/lib/types/toast.types.ts +export interface ToastMessage { + id: string; + type: ToastType; + title?: string; + message: string; + duration?: number; + actions?: ToastAction[]; + persistent?: boolean; +} + +export type ToastType = 'success' | 'error' | 'warning' | 'info'; + +export interface ToastAction { + label: string; + action: () => void; + type?: 'primary' | 'secondary'; +} + +export interface ToastConfig { + position: ToastPosition; + maxToasts: number; + defaultDuration: number; + enableSound: boolean; +} + +export type ToastPosition = + | 'top-right' + | 'top-left' + | 'bottom-right' + | 'bottom-left' + | 'top-center' + | 'bottom-center'; +``` + +## 📋 Детальный план реализации + +### **Этап 1: Создание ToastService (5-7 часов)** + +#### 1.1 Базовый ToastService +```typescript +@Injectable({ providedIn: 'root' }) +export class ToastService { + private readonly toastQueue = signal([]); + private readonly config = signal({ + position: 'top-right', + maxToasts: 5, + defaultDuration: 5000, + enableSound: false, + }); + + readonly toasts = this.toastQueue.asReadonly(); + + success(message: string, title?: string, options?: Partial): void { + this.show({ type: 'success', message, title, ...options }); + } + + error(message: string, title?: string, options?: Partial): void { + this.show({ type: 'error', message, title, persistent: true, ...options }); + } + + warning(message: string, title?: string, options?: Partial): void { + this.show({ type: 'warning', message, title, ...options }); + } + + info(message: string, title?: string, options?: Partial): void { + this.show({ type: 'info', message, title, ...options }); + } + + private show(toast: Omit): void { + const id = this.generateId(); + const newToast: ToastMessage = { + id, + duration: this.config().defaultDuration, + ...toast, + }; + + this.toastQueue.update(toasts => { + const updated = [...toasts, newToast]; + return updated.slice(-this.config().maxToasts); + }); + + if (newToast.duration && newToast.duration > 0) { + setTimeout(() => this.dismiss(id), newToast.duration); + } + } + + dismiss(id: string): void { + this.toastQueue.update(toasts => toasts.filter(t => t.id !== id)); + } + + dismissAll(): void { + this.toastQueue.set([]); + } + + private generateId(): string { + return `toast-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; + } +} +``` + +#### 1.2 ToastComponent +```typescript +@Component({ + selector: 'app-toast', + template: ` +
+ @if (toast.title) { +
{{ toast.title }}
+ } +
{{ toast.message }}
+ @if (toast.actions && toast.actions.length > 0) { +
+ @for (action of toast.actions; track action.label) { + + } +
+ } + +
+ `, + styleUrls: ['./toast.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ToastComponent { + @Input({ required: true }) toast!: ToastMessage; + @Output() dismiss = new EventEmitter(); + + onDismiss(): void { + this.dismiss.emit(this.toast.id); + } +} +``` + +#### 1.3 ToastContainerComponent +```typescript +@Component({ + selector: 'app-toast-container', + template: ` +
+ @for (toast of toasts(); track toast.id) { + + } +
+ `, + styleUrls: ['./toast-container.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ToastContainerComponent { + private readonly toastService = inject(ToastService); + private readonly configService = inject(ToastConfigService); + + readonly toasts = this.toastService.toasts; + readonly position = this.configService.position; + + onDismiss(id: string): void { + this.toastService.dismiss(id); + } +} +``` + +### **Этап 2: Интеграция с API Error Handling (5-7 часов)** + +#### 2.1 ToastErrorMapperService +```typescript +@Injectable({ providedIn: 'root' }) +export class ToastErrorMapperService { + private readonly errorMessages: Record = { + 'NETWORK_ERROR': 'Network connection error. Please check your internet connection.', + 'TIMEOUT': 'Request timeout. Please try again.', + 'UNAUTHORIZED': 'Authentication required. Please login again.', + 'FORBIDDEN': 'Access denied. You don\'t have permission to perform this action.', + 'NOT_FOUND': 'Requested resource not found.', + 'VALIDATION_ERROR': 'Please check your input and try again.', + 'SERVER_ERROR': 'Server error occurred. Please try again later.', + 'RATE_LIMIT': 'Too many requests. Please wait a moment and try again.', + }; + + private readonly errorActions: Record = { + 'NETWORK_ERROR': [ + { label: 'Retry', action: () => this.retryAction(), type: 'primary' }, + { label: 'Dismiss', action: () => {}, type: 'secondary' }, + ], + 'UNAUTHORIZED': [ + { label: 'Login', action: () => this.navigateToLogin(), type: 'primary' }, + ], + }; + + mapApiErrorToToast(error: ApiError): ToastMessage { + const message = this.errorMessages[error.code] || error.message || 'An unexpected error occurred.'; + const actions = this.errorActions[error.code] || []; + + return { + id: this.generateId(), + type: this.getToastType(error.code), + title: this.getErrorTitle(error.code), + message, + actions: actions.length > 0 ? actions : undefined, + persistent: this.isPersistentError(error.code), + }; + } + + private getToastType(errorCode: string): ToastType { + const errorTypeMap: Record = { + 'NETWORK_ERROR': 'error', + 'TIMEOUT': 'error', + 'UNAUTHORIZED': 'warning', + 'FORBIDDEN': 'warning', + 'NOT_FOUND': 'warning', + 'VALIDATION_ERROR': 'warning', + 'SERVER_ERROR': 'error', + 'RATE_LIMIT': 'warning', + }; + + return errorTypeMap[errorCode] || 'error'; + } + + private getErrorTitle(errorCode: string): string { + const titleMap: Record = { + 'NETWORK_ERROR': 'Connection Error', + 'TIMEOUT': 'Request Timeout', + 'UNAUTHORIZED': 'Authentication Required', + 'FORBIDDEN': 'Access Denied', + 'NOT_FOUND': 'Not Found', + 'VALIDATION_ERROR': 'Validation Error', + 'SERVER_ERROR': 'Server Error', + 'RATE_LIMIT': 'Rate Limited', + }; + + return titleMap[errorCode] || 'Error'; + } + + private isPersistentError(errorCode: string): boolean { + return ['UNAUTHORIZED', 'FORBIDDEN', 'SERVER_ERROR'].includes(errorCode); + } + + private retryAction(): void { + // Implement retry logic + } + + private navigateToLogin(): void { + // Navigate to login page + } + + private generateId(): string { + return `error-toast-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; + } +} +``` + +#### 2.2 ApiErrorInterceptor +```typescript +@Injectable() +export class ApiErrorInterceptor implements HttpInterceptor { + private readonly toastService = inject(ToastService); + private readonly errorMapper = inject(ToastErrorMapperService); + + intercept(req: HttpRequest, next: HttpHandler): Observable> { + return next.handle(req).pipe( + catchError((error: HttpErrorResponse) => { + const apiError = this.mapHttpErrorToApiError(error); + const toastMessage = this.errorMapper.mapApiErrorToToast(apiError); + + this.toastService.error( + toastMessage.message, + toastMessage.title, + { + actions: toastMessage.actions, + persistent: toastMessage.persistent, + } + ); + + return throwError(() => apiError); + }) + ); + } + + private mapHttpErrorToApiError(error: HttpErrorResponse): ApiError { + const errorCode = this.getErrorCode(error); + const message = error.error?.message || error.message || 'Unknown error'; + + return { + code: errorCode, + message, + status: error.status, + timestamp: new Date().toISOString(), + }; + } + + private getErrorCode(error: HttpErrorResponse): string { + if (!navigator.onLine) return 'NETWORK_ERROR'; + if (error.status === 0) return 'NETWORK_ERROR'; + if (error.status === 401) return 'UNAUTHORIZED'; + if (error.status === 403) return 'FORBIDDEN'; + if (error.status === 404) return 'NOT_FOUND'; + if (error.status === 422) return 'VALIDATION_ERROR'; + if (error.status === 429) return 'RATE_LIMIT'; + if (error.status >= 500) return 'SERVER_ERROR'; + + return 'UNKNOWN_ERROR'; + } +} +``` + +#### 2.3 Интеграция с существующими сервисами +```typescript +// В AuthService +@Injectable({ providedIn: 'root' }) +export class AuthService { + private readonly toastService = inject(ToastService); + + login$(body: LoginRequest): Observable { + this.loading.set(true); + this.error.set(null); + + return this.authApi.login$(body).pipe( + tap(() => { + this.toastService.success('Welcome back!', 'Login successful'); + }), + catchError((error: ApiError) => { + // Toast уже показан через interceptor + this.error.set(error.message); + return of(undefined); + }), + finalize(() => this.loading.set(false)), + ); + } +} + +// В CalorieApiService +@Injectable({ providedIn: 'root' }) +export class CalorieApiService { + private readonly toastService = inject(ToastService); + + calculateCalories(data: CalorieCalculationData): Observable { + return this.http.post('/api/v1/calorie/calculate', data).pipe( + tap(() => { + this.toastService.success('Calories calculated successfully!'); + }), + catchError((error: ApiError) => { + // Toast уже показан через interceptor + return throwError(() => error); + }) + ); + } +} +``` + +## 🧪 Тестирование + +### **Unit тесты** +- [ ] ToastService - тестирование всех методов +- [ ] ToastErrorMapperService - тестирование маппинга ошибок +- [ ] ToastComponent - тестирование отображения +- [ ] ToastContainerComponent - тестирование управления + +### **Integration тесты** +- [ ] Интеграция с API interceptor +- [ ] Интеграция с существующими сервисами +- [ ] Тестирование различных типов ошибок +- [ ] Тестирование действий в toast'ах + +### **E2E тесты** +- [ ] Отображение toast'ов в UI +- [ ] Автоматическое исчезновение +- [ ] Действия пользователя (dismiss, retry) +- [ ] Обработка ошибок API + +## 📈 Метрики успеха + +### **Функциональные метрики** +- [ ] Все типы ошибок API показывают соответствующие toast'ы +- [ ] Toast'ы появляются и исчезают корректно +- [ ] Действия в toast'ах работают правильно +- [ ] Интеграция с существующими сервисами работает + +### **UX метрики** +- [ ] Понятные сообщения об ошибках +- [ ] Быстрая обратная связь для пользователя +- [ ] Не мешает основному интерфейсу +- [ ] Адаптируется под тему приложения + +### **Технические метрики** +- [ ] Покрытие тестами > 90% +- [ ] Производительность не ухудшается +- [ ] Размер bundle не увеличивается значительно +- [ ] Совместимость с существующими функциями + +## 🚀 План реализации + +### **Неделя 1: Создание ToastService** +- День 1-2: Базовый ToastService и компоненты +- День 3-4: Стилизация и анимации +- День 5: Тестирование и интеграция + +### **Неделя 2: Интеграция с API** +- День 1-2: ToastErrorMapperService и ApiErrorInterceptor +- День 3-4: Интеграция с существующими сервисами +- День 5: Тестирование и финальная проверка + +## 🔗 Зависимости + +### **Внутренние зависимости** +- Taiga UI - для компонентов и стилизации +- ThemeService - для адаптации под тему +- AuthService - для ошибок авторизации +- CalorieApiService - для ошибок расчета калорий +- UserApiService - для ошибок пользовательских данных + +### **Внешние зависимости** +- Angular HTTP Interceptors +- RxJS для обработки ошибок +- CSS animations для анимаций + +## 📋 Чеклист готовности + +### **Перед началом** +- [ ] Проанализировать существующие ошибки API +- [ ] Определить типы ошибок и сообщения +- [ ] Создать архитектуру сервисов +- [ ] Настроить тестовую среду + +### **Во время разработки** +- [ ] Следовать принципам FSD архитектуры +- [ ] Писать тесты для каждого сервиса +- [ ] Документировать API и интерфейсы +- [ ] Проверять совместимость с существующим кодом + +### **После завершения** +- [ ] Провести полное тестирование +- [ ] Оптимизировать производительность +- [ ] Обновить документацию +- [ ] Подготовить к продакшену + +## 🎯 Ожидаемые результаты + +### **Для пользователей** +- Понятные сообщения об ошибках +- Быстрая обратная связь +- Возможность действий с ошибками (retry, dismiss) +- Улучшенный UX приложения + +### **Для разработчиков** +- Унифицированная система обработки ошибок +- Легкое добавление новых типов ошибок +- Централизованное управление сообщениями +- Хорошее покрытие тестами + +### **Для бизнеса** +- Снижение количества обращений в поддержку +- Улучшенное понимание ошибок пользователями +- Повышенная надежность приложения +- Лучший пользовательский опыт + +## ⚠️ Риски и митигация + +### **Потенциальные риски** +1. **Перегрузка интерфейса toast'ами** + - Митигация: Ограничение количества одновременных toast'ов +2. **Дублирование сообщений** + - Митигация: Дедупликация по типу ошибки +3. **Производительность** + - Митигация: Ленивая загрузка и оптимизация + +### **Критерии остановки** +- Если toast'ы мешают основному функционалу +- Если производительность значительно ухудшается +- Если пользователи жалуются на избыточность уведомлений + +## 🎯 Заключение + +Данный план обеспечивает создание универсальной системы toast-уведомлений, которая значительно улучшит пользовательский опыт при работе с ошибками API в приложении Strive. + +**Общий бюджет времени:** 10-14 часов +**Ожидаемое улучшение UX:** Значительное улучшение обратной связи с пользователем diff --git a/docs/plans/calorie-service-frontend-integration.md b/docs/plans/calorie-service-frontend-integration.md deleted file mode 100644 index ae9d687..0000000 --- a/docs/plans/calorie-service-frontend-integration.md +++ /dev/null @@ -1,60 +0,0 @@ -## Calorie Service Frontend Integration Plan (Angular → Go backend) - -### Goals -- Replace in-browser calculations with Go API calls. -- Remove localStorage usage. -- Leverage PWA capabilities for resilient UX: offline queue, background sync, caching. - -### API Contracts -- POST `/api/calories/calculate` → `CalorieResults` -- GET `/api/calories/last` → `{ data, results } | 404` -- JSON fields match current TS models. - -### Angular Changes -- `CalorieApiService`: - - `calculateCalories(data)` → `HttpClient.post` - - `getCaloriesResult()` → `HttpClient.get<{data: CalorieCalculationData; results: CalorieResults} | null>` - - Remove `setTimeout` and client-side formulas (optionally keep as fallback behind feature flag) -- `CalorieCalculatorService` remains the same (signals/state unchanged). -- Add `ApiBaseUrl` configuration via environments. - -### PWA Enhancements (no localStorage) -- IndexedDB Request Queue - - Store pending calculation requests when offline - - Replay on reconnect (online event) or via Background Sync -- Background Sync (if supported) - - Register sync tag `calories-calc-sync` - - Service Worker consumes queued requests and POSTs to backend -- Caching Strategy via Angular Service Worker - - `ngsw-config.json`: dataGroups for - - `POST /api/calories/calculate` → freshness (no cache of responses, but queue when offline) - - `GET /api/calories/last` → performance with short maxAge and ETag revalidation -- ETag/If-None-Match - - Use ETag headers from backend for `last` endpoint; SW respects 304 - -### Error Handling -- Unified API error mapper (status → user-visible message) -- Timeouts and retry with backoff for idempotent `GET /last` only -- For `POST /calculate` avoid automatic retries in foreground; rely on queue/sync - -### Security -- Add interceptor for Telegram initData/JWT header -- CORS aligned on backend - -### Testing -- HttpClientTestingModule specs for both methods (200/404/error) -- E2E or integration test covering offline queue replay (can be documented/manual if complex) - -### Migration Steps -1. Implement backend (per backend plan) -2. Add Angular env `apiBaseUrl` and HTTP interceptor -3. Replace `CalorieApiService` internals with HttpClient -4. Configure `ngsw-config.json` dataGroups (cache + queue) -5. Implement IndexedDB queue + SW sync handler -6. Update docs and remove old client-side logic - -### Open Questions -- Auth source: Telegram initData or other? -- Should client fallback to local compute when offline (feature flag)? Default: no. - - diff --git a/ngsw-config.json b/ngsw-config.json index cb4b243..feda3d7 100644 --- a/ngsw-config.json +++ b/ngsw-config.json @@ -49,6 +49,6 @@ } ], "appData": { - "version": "1.0.7" + "version": "1.0.8" } } diff --git a/package-lock.json b/package-lock.json index 57d3191..51cee50 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,7 +47,6 @@ "@angular/compiler-cli": "^19.2.0", "@types/jasmine": "~5.1.0", "@types/telegram-web-app": "^9.0.0", - "angular-cli-ghpages": "^1.0.3", "angular-eslint": "20.1.1", "eslint-config-prettier": "^10.1.8", "eslint-import-resolver-typescript": "^3.6.1", @@ -100,81 +99,43 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1601.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1601.8.tgz", - "integrity": "sha512-kOXVGwsQnZvtz2UZNefcEy64Jiwq0eSoQUeozvDXOaYRJABLjPKI2YaarvKC9/Z1SGLuje0o/eRJO4T8aRk9rQ==", + "version": "0.1902.18", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1902.18.tgz", + "integrity": "sha512-3AyIlxbJWmWJm/CPS6S57kWBydMdYUPtF+SK8tqzwcBnyRbLwXoI7UbxstZ/C9J1hAY8QdZrDYGotwlHwhiC8g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@angular-devkit/core": "16.1.8", + "@angular-devkit/core": "19.2.18", "rxjs": "7.8.1" }, "engines": { - "node": "^16.14.0 || >=18.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular-devkit/architect/node_modules/@angular-devkit/core": { - "version": "16.1.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.1.8.tgz", - "integrity": "sha512-dSRD/+bGanArIXkj+kaU1kDFleZeQMzmBiOXX+pK0Ah9/0Yn1VmY3RZh1zcX9vgIQXV+t7UPrTpOjaERMUtVGw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ajv": "8.12.0", - "ajv-formats": "2.1.1", - "jsonc-parser": "3.2.0", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0", + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } } }, - "node_modules/@angular-devkit/architect/node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true, - "license": "MIT", - "peer": true - }, "node_modules/@angular-devkit/architect/node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "tslib": "^2.1.0" } }, "node_modules/@angular-devkit/build-angular": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-19.2.15.tgz", - "integrity": "sha512-mqudAcyrSp/E7ZQdQoHfys0/nvQuwyJDaAzj3qL3HUStuUzb5ULNOj2f6sFBo+xYo+/WT8IzmzDN9DCqDgvFaA==", + "version": "19.2.18", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-19.2.18.tgz", + "integrity": "sha512-OFrNsWT7GovW2MX4nDx2U9bEsAhOhJUbTm2qibMUSnVjm/iJhdcZXRB7qmDjetVp68nAXvcHCPPIo+2WlfLdig==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.1902.15", - "@angular-devkit/build-webpack": "0.1902.15", - "@angular-devkit/core": "19.2.15", - "@angular/build": "19.2.15", + "@angular-devkit/architect": "0.1902.18", + "@angular-devkit/build-webpack": "0.1902.18", + "@angular-devkit/core": "19.2.18", + "@angular/build": "19.2.18", "@babel/core": "7.26.10", "@babel/generator": "7.26.10", "@babel/helper-annotate-as-pure": "7.25.9", @@ -185,7 +146,7 @@ "@babel/preset-env": "7.26.9", "@babel/runtime": "7.26.10", "@discoveryjs/json-ext": "0.6.3", - "@ngtools/webpack": "19.2.15", + "@ngtools/webpack": "19.2.18", "@vitejs/plugin-basic-ssl": "1.2.0", "ansi-colors": "4.1.3", "autoprefixer": "10.4.20", @@ -239,7 +200,7 @@ "@angular/localize": "^19.0.0 || ^19.2.0-next.0", "@angular/platform-server": "^19.0.0 || ^19.2.0-next.0", "@angular/service-worker": "^19.0.0 || ^19.2.0-next.0", - "@angular/ssr": "^19.2.15", + "@angular/ssr": "^19.2.18", "@web/test-runner": "^0.20.0", "browser-sync": "^3.0.2", "jest": "^29.5.0", @@ -289,85 +250,6 @@ } } }, - "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/architect": { - "version": "0.1902.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1902.15.tgz", - "integrity": "sha512-RbqhStc6ZoRv57ZqLB36VOkBkAdU3nNezCvIs0AJV5V4+vLPMrb0hpIB0sF+9yMlMjWsolnRsj0/Fil+zQG3bw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "19.2.15", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.15.tgz", - "integrity": "sha512-pU2RZYX6vhd7uLSdLwPnuBcr0mXJSjp3EgOXKsrlQFQZevc+Qs+2JdXgIElnOT/aDqtRtriDmLlSbtdE8n3ZbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "8.17.1", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.2", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^4.0.0" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, "node_modules/@angular-devkit/build-angular/node_modules/postcss": { "version": "8.5.2", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz", @@ -408,13 +290,13 @@ } }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.1902.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1902.15.tgz", - "integrity": "sha512-pIfZeizWsViXx8bsMoBLZw7Tl7uFf7bM7hAfmNwk0bb0QGzx5k1BiW6IKWyaG+Dg6U4UCrlNpIiut2b78HwQZw==", + "version": "0.1902.18", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1902.18.tgz", + "integrity": "sha512-pOo8HFEE92MdL6BwBvvWb8wiZ8Y3KHRPewG3pwHdJfL3pCVP3oNThJnFVLxrA/LxJK7kFRzKexhqd89OteZiYw==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/architect": "0.1902.15", + "@angular-devkit/architect": "0.1902.18", "rxjs": "7.8.1" }, "engines": { @@ -427,85 +309,6 @@ "webpack-dev-server": "^5.0.2" } }, - "node_modules/@angular-devkit/build-webpack/node_modules/@angular-devkit/architect": { - "version": "0.1902.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1902.15.tgz", - "integrity": "sha512-RbqhStc6ZoRv57ZqLB36VOkBkAdU3nNezCvIs0AJV5V4+vLPMrb0hpIB0sF+9yMlMjWsolnRsj0/Fil+zQG3bw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "19.2.15", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular-devkit/build-webpack/node_modules/@angular-devkit/core": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.15.tgz", - "integrity": "sha512-pU2RZYX6vhd7uLSdLwPnuBcr0mXJSjp3EgOXKsrlQFQZevc+Qs+2JdXgIElnOT/aDqtRtriDmLlSbtdE8n3ZbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "8.17.1", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.2", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^4.0.0" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@angular-devkit/build-webpack/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@angular-devkit/build-webpack/node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, "node_modules/@angular-devkit/build-webpack/node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -517,26 +320,26 @@ } }, "node_modules/@angular-devkit/core": { - "version": "16.2.16", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.2.16.tgz", - "integrity": "sha512-5xHs9JFmp78sydrOAg0UGErxfMVv5c2f3RXoikS7eBOOXTWEi5pmnOkOvSJ3loQFGVs3Y7i+u02G3VrF5ZxOrA==", + "version": "19.2.18", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.18.tgz", + "integrity": "sha512-D/JbeM3yAZ6Cnk/3ez8MvoTjx1pgUnkJHvDkuMhRuelCi3m0b0Qt/3548ie7CU+oLHdzAzjFhEvCPNssdevTRQ==", "devOptional": true, "license": "MIT", "dependencies": { - "ajv": "8.12.0", - "ajv-formats": "2.1.1", - "jsonc-parser": "3.2.0", - "picomatch": "2.3.1", + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", "rxjs": "7.8.1", "source-map": "0.7.4" }, "engines": { - "node": "^16.14.0 || >=18.10.0", + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" }, "peerDependencies": { - "chokidar": "^3.5.2" + "chokidar": "^4.0.0" }, "peerDependenciesMeta": { "chokidar": { @@ -544,26 +347,6 @@ } } }, - "node_modules/@angular-devkit/core/node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/@angular-devkit/core/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@angular-devkit/core/node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -575,31 +358,24 @@ } }, "node_modules/@angular-devkit/schematics": { - "version": "16.2.16", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.2.16.tgz", - "integrity": "sha512-pF6fdtJh6yLmgA7Gs45JIdxPl2MsTAhYcZIMrX1a6ID64dfwtF0MP8fDE6vrWInV1zXbzzf7l7PeKuqVtTSzKg==", + "version": "19.2.18", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.18.tgz", + "integrity": "sha512-DYiQDKv2jnT0j+d8SeWynCCGERWIYDkdS6bQKiO7rSc7ChXby2fFZZ7VpcEHGv7l2K2/I+q9mZTG0i/g5mSzCg==", "devOptional": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "16.2.16", - "jsonc-parser": "3.2.0", - "magic-string": "0.30.1", + "@angular-devkit/core": "19.2.18", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.17", "ora": "5.4.1", "rxjs": "7.8.1" }, "engines": { - "node": "^16.14.0 || >=18.10.0", + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" } }, - "node_modules/@angular-devkit/schematics/node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "devOptional": true, - "license": "MIT" - }, "node_modules/@angular-devkit/schematics/node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -626,13 +402,13 @@ } }, "node_modules/@angular-eslint/builder/node_modules/@angular-devkit/architect": { - "version": "0.2002.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2002.2.tgz", - "integrity": "sha512-amppp/UqKyj+B8hYFU16j4t6SVN+SS0AEnHivDjKy41NNJgXv+5Sm2Q2jaMHviCT3rclyT0wqwNAi0RDjyLx5Q==", + "version": "0.2003.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2003.7.tgz", + "integrity": "sha512-NGHLfrNQNjwWwvyQomMM1AqRaqH3UU0TwySJh9XlSc9dC/roB5zD2NjLf98K4LfAIfHvDBwkQ+dMo3F556/Xuw==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "20.2.2", + "@angular-devkit/core": "20.3.7", "rxjs": "7.8.2" }, "engines": { @@ -642,9 +418,9 @@ } }, "node_modules/@angular-eslint/builder/node_modules/@angular-devkit/core": { - "version": "20.2.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.2.2.tgz", - "integrity": "sha512-SC+f5isSWJBpEgR+R7jP++2Z14WExNWLAdKpIickLWjuL8FlGkj+kaF3dWXhh0KcXo+r6kKb4pWUptSaqer5gA==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.7.tgz", + "integrity": "sha512-psmcjwYcXve4sLrcdnARc15/Wfd3RpydbtLo9+mViNzk5HQ6L2eEztKl/2QVYMgzZVIa1GfhjwUllVCyLAv3sg==", "dev": true, "license": "MIT", "dependencies": { @@ -669,41 +445,6 @@ } } }, - "node_modules/@angular-eslint/builder/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@angular-eslint/builder/node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, "node_modules/@angular-eslint/builder/node_modules/picomatch": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", @@ -728,21 +469,21 @@ } }, "node_modules/@angular-eslint/bundled-angular-compiler": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-20.2.0.tgz", - "integrity": "sha512-9NhytRavpxWqa0fK+mlQZrif91MhtG3VEV3JCQEwOH9JPueY95XVHYwPgcbODhoSg/z5YaTVby5G254cEXUMew==", + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-20.4.0.tgz", + "integrity": "sha512-u3I/yABCm+lda/AdnLKJnjdQp1i4BACgEKY9D6eKIgijcRtlvUc6Jq+43e1oPZLj+3DdrlABNcB8HsA/+RzikA==", "dev": true, "license": "MIT" }, "node_modules/@angular-eslint/eslint-plugin": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-20.2.0.tgz", - "integrity": "sha512-HdujUz7Q1ZW371cCJRkUcp0bjU/iP8Z/ZNTStCzMd4euu+HwVt69dLsTCs6f1i6SMqlIUjaP8TbqNo5nV8Altw==", + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-20.4.0.tgz", + "integrity": "sha512-gSQO18QLHt46UFjDcxkGhuFMKl4sPdFDnCZRZDpZC+4OZQ64f+xazPOveSoK1o4ttjSulfyXslE+I9bESmR5Mw==", "dev": true, "license": "MIT", "dependencies": { - "@angular-eslint/bundled-angular-compiler": "20.2.0", - "@angular-eslint/utils": "20.2.0", + "@angular-eslint/bundled-angular-compiler": "20.4.0", + "@angular-eslint/utils": "20.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { @@ -752,19 +493,19 @@ } }, "node_modules/@angular-eslint/eslint-plugin-template": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-20.2.0.tgz", - "integrity": "sha512-pRuROa9QUUIq/ulB5rbXrwOhFA1tcR8HhGq187gFQfPno/bFZfbF9R8x+zukbVipNjl087WHUWj09KNDcJBLlA==", + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-20.4.0.tgz", + "integrity": "sha512-AWXtpWfivSE3PIwTPkuACPww5qu8dn3p1nuGuk2M/3LoHJFAMVvH6y2toTqGSUSTKALSdYzGhxbRPyDy6aEzDw==", "dev": true, "license": "MIT", "dependencies": { - "@angular-eslint/bundled-angular-compiler": "20.2.0", - "@angular-eslint/utils": "20.2.0", + "@angular-eslint/bundled-angular-compiler": "20.4.0", + "@angular-eslint/utils": "20.4.0", "aria-query": "5.3.2", "axobject-query": "4.1.0" }, "peerDependencies": { - "@angular-eslint/template-parser": "20.2.0", + "@angular-eslint/template-parser": "20.4.0", "@typescript-eslint/types": "^7.11.0 || ^8.0.0", "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", "eslint": "^8.57.0 || ^9.0.0", @@ -788,9 +529,9 @@ } }, "node_modules/@angular-eslint/schematics/node_modules/@angular-devkit/core": { - "version": "20.2.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.2.2.tgz", - "integrity": "sha512-SC+f5isSWJBpEgR+R7jP++2Z14WExNWLAdKpIickLWjuL8FlGkj+kaF3dWXhh0KcXo+r6kKb4pWUptSaqer5gA==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.7.tgz", + "integrity": "sha512-psmcjwYcXve4sLrcdnARc15/Wfd3RpydbtLo9+mViNzk5HQ6L2eEztKl/2QVYMgzZVIa1GfhjwUllVCyLAv3sg==", "dev": true, "license": "MIT", "dependencies": { @@ -816,13 +557,13 @@ } }, "node_modules/@angular-eslint/schematics/node_modules/@angular-devkit/schematics": { - "version": "20.2.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-20.2.2.tgz", - "integrity": "sha512-rtL7slZjzdChQoiADKZv/Ra8D3C3tIw/WcVxd2stiLHdK/Oaf9ejx5m/X9o0QMEbNsy2Fy/RKodNqmz1CjzpCg==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-20.3.7.tgz", + "integrity": "sha512-DUxcQBPKO69p56ZgIdVfxWyLiSjdcUoD6BH9/nWHp0QiqRAR6GcXP4SFax76JPl2WsiCp4hHZ233Hf69AP1xew==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "20.2.2", + "@angular-devkit/core": "20.3.7", "jsonc-parser": "3.3.1", "magic-string": "0.30.17", "ora": "8.2.0", @@ -909,62 +650,27 @@ "typescript": "*" } }, - "node_modules/@angular-eslint/schematics/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "node_modules/@angular-eslint/schematics/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "dev": true, "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@angular-eslint/schematics/node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "node_modules/@angular-eslint/schematics/node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", "dev": true, "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/@angular-eslint/schematics/node_modules/chalk": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.0.tgz", - "integrity": "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@angular-eslint/schematics/node_modules/is-interactive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", - "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" + "engines": { + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -1013,16 +719,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@angular-eslint/schematics/node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, "node_modules/@angular-eslint/schematics/node_modules/ora": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", @@ -1084,13 +780,13 @@ } }, "node_modules/@angular-eslint/template-parser": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-20.2.0.tgz", - "integrity": "sha512-72hskYThlVhktpRCwSwAohY/SxUoMv0hhS71zjlJcHFTzTAWCI8Zy2U4OJuhUO7+XWL6iAu13NKzJKRzUhGdSw==", + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-20.4.0.tgz", + "integrity": "sha512-5Vyo/VJ1DrIsAkudFpZj1f7CpCLYuiTzTQksHTiZE18iYsLKRkEC7y9S6+TiHrdD96rhNxL28Pz9FDU4lIBjkw==", "dev": true, "license": "MIT", "dependencies": { - "@angular-eslint/bundled-angular-compiler": "20.2.0", + "@angular-eslint/bundled-angular-compiler": "20.4.0", "eslint-scope": "^8.0.2" }, "peerDependencies": { @@ -1099,13 +795,13 @@ } }, "node_modules/@angular-eslint/utils": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-20.2.0.tgz", - "integrity": "sha512-GnEa8BU9xBLUq4JQ8UgXecUXPCmju9P5KIobql17LV1t3vnJ33Zr7acO1jWOzluypllKSVrtARdRTI+TQGCqrA==", + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-20.4.0.tgz", + "integrity": "sha512-SkR4fdPc+40W/53JmF6Nz6EIXIxvoRzhOdUiHoBKr/6fWONQwm7Vq55vk11AdK/oKTDUQCJ84HExQw6mzFljtg==", "dev": true, "license": "MIT", "dependencies": { - "@angular-eslint/bundled-angular-compiler": "20.2.0" + "@angular-eslint/bundled-angular-compiler": "20.4.0" }, "peerDependencies": { "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", @@ -1114,9 +810,9 @@ } }, "node_modules/@angular/animations": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-19.2.14.tgz", - "integrity": "sha512-xhl8fLto5HHJdVj8Nb6EoBEiTAcXuWDYn1q5uHcGxyVH3kiwENWy/2OQXgCr2CuWo2e6hNUGzSLf/cjbsMNqEA==", + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-19.2.15.tgz", + "integrity": "sha512-eq9vokLU8bjs7g/Znz8zJUQEOhT0MAJ/heBCHbB35S+CtZXJmItrsEqkI1tsRiR58NKXB6cbhBhULVo6qJbhXQ==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1125,19 +821,19 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "19.2.14", - "@angular/core": "19.2.14" + "@angular/common": "19.2.15", + "@angular/core": "19.2.15" } }, "node_modules/@angular/build": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@angular/build/-/build-19.2.15.tgz", - "integrity": "sha512-iE4fp4d5ALu702uoL6/YkjM2JlGEXZ5G+RVzq3W2jg/Ft6ISAQnRKB6mymtetDD6oD7i87e8uSu9kFVNBauX2w==", + "version": "19.2.18", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-19.2.18.tgz", + "integrity": "sha512-dUpcqiryCunKdIF3FnVeO0tkxXctOk1JTaVoIA9vTW1fV8zdtRMVduq5yikE3Z3ec3AIC/2F+afD6BcF2fqliQ==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.1902.15", + "@angular-devkit/architect": "0.1902.18", "@babel/core": "7.26.10", "@babel/helper-annotate-as-pure": "7.25.9", "@babel/helper-split-export-declaration": "7.24.7", @@ -1160,7 +856,7 @@ "sass": "1.85.0", "semver": "7.7.1", "source-map-support": "0.5.21", - "vite": "6.2.7", + "vite": "6.3.6", "watchpack": "2.4.2" }, "engines": { @@ -1177,7 +873,7 @@ "@angular/localize": "^19.0.0 || ^19.2.0-next.0", "@angular/platform-server": "^19.0.0 || ^19.2.0-next.0", "@angular/service-worker": "^19.0.0 || ^19.2.0-next.0", - "@angular/ssr": "^19.2.15", + "@angular/ssr": "^19.2.18", "karma": "^6.4.0", "less": "^4.2.0", "ng-packagr": "^19.0.0 || ^19.2.0-next.0", @@ -1215,115 +911,243 @@ } } }, - "node_modules/@angular/build/node_modules/@angular-devkit/architect": { - "version": "0.1902.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1902.15.tgz", - "integrity": "sha512-RbqhStc6ZoRv57ZqLB36VOkBkAdU3nNezCvIs0AJV5V4+vLPMrb0hpIB0sF+9yMlMjWsolnRsj0/Fil+zQG3bw==", + "node_modules/@angular/build/node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz", + "integrity": "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", - "dependencies": { - "@angular-devkit/core": "19.2.15", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@angular/build/node_modules/@angular-devkit/core": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.15.tgz", - "integrity": "sha512-pU2RZYX6vhd7uLSdLwPnuBcr0mXJSjp3EgOXKsrlQFQZevc+Qs+2JdXgIElnOT/aDqtRtriDmLlSbtdE8n3ZbA==", + "node_modules/@angular/build/node_modules/@rollup/rollup-android-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz", + "integrity": "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "ajv": "8.17.1", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.2", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^4.0.0" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@angular/build/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "node_modules/@angular/build/node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.5.tgz", + "integrity": "sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/@angular/build/node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "node_modules/@angular/build/node_modules/@rollup/rollup-darwin-x64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz", + "integrity": "sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/@angular/build/node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "node_modules/@angular/build/node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz", + "integrity": "sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } + "optional": true, + "os": [ + "freebsd" + ] }, - "node_modules/@angular/build/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "node_modules/@angular/build/node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz", + "integrity": "sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz", + "integrity": "sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz", + "integrity": "sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz", + "integrity": "sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz", + "integrity": "sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz", + "integrity": "sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz", + "integrity": "sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz", + "integrity": "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz", + "integrity": "sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz", + "integrity": "sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz", + "integrity": "sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, "node_modules/@angular/build/node_modules/vite": { - "version": "6.2.7", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.7.tgz", - "integrity": "sha512-qg3LkeuinTrZoJHHF94coSaTfIPyBYoywp+ys4qu20oSJFbKMYoIJo0FWJT9q6Vp49l6z9IsJRbHdcGtiKbGoQ==", + "version": "6.3.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.6.tgz", + "integrity": "sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", "postcss": "^8.5.3", - "rollup": "^4.30.1" + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" }, "bin": { "vite": "bin/vite.js" @@ -1386,177 +1210,101 @@ } } }, - "node_modules/@angular/cdk": { - "version": "19.2.19", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-19.2.19.tgz", - "integrity": "sha512-PCpJagurPBqciqcq4Z8+3OtKLb7rSl4w/qBJoIMua8CgnrjvA1i+SWawhdtfI1zlY8FSwhzLwXV0CmWWfFzQPg==", - "license": "MIT", - "dependencies": { - "parse5": "^7.1.2", - "tslib": "^2.3.0" - }, - "peerDependencies": { - "@angular/common": "^19.0.0 || ^20.0.0", - "@angular/core": "^19.0.0 || ^20.0.0", - "rxjs": "^6.5.3 || ^7.4.0" - } - }, - "node_modules/@angular/cli": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-19.2.15.tgz", - "integrity": "sha512-YRIpARHWSOnWkHusUWTQgeUrPWMjWvtQrOkjWc6stF36z2KUzKMEng6EzUvH6sZolNSwVwOFpODEP0ut4aBkvQ==", + "node_modules/@angular/build/node_modules/vite/node_modules/rollup": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz", + "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/architect": "0.1902.15", - "@angular-devkit/core": "19.2.15", - "@angular-devkit/schematics": "19.2.15", - "@inquirer/prompts": "7.3.2", - "@listr2/prompt-adapter-inquirer": "2.0.18", - "@schematics/angular": "19.2.15", - "@yarnpkg/lockfile": "1.1.0", - "ini": "5.0.0", - "jsonc-parser": "3.3.1", - "listr2": "8.2.5", - "npm-package-arg": "12.0.2", - "npm-pick-manifest": "10.0.0", - "pacote": "20.0.0", - "resolve": "1.22.10", - "semver": "7.7.1", - "symbol-observable": "4.0.0", - "yargs": "17.7.2" + "@types/estree": "1.0.8" }, "bin": { - "ng": "bin/ng.js" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular/cli/node_modules/@angular-devkit/architect": { - "version": "0.1902.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1902.15.tgz", - "integrity": "sha512-RbqhStc6ZoRv57ZqLB36VOkBkAdU3nNezCvIs0AJV5V4+vLPMrb0hpIB0sF+9yMlMjWsolnRsj0/Fil+zQG3bw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "19.2.15", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular/cli/node_modules/@angular-devkit/core": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.15.tgz", - "integrity": "sha512-pU2RZYX6vhd7uLSdLwPnuBcr0mXJSjp3EgOXKsrlQFQZevc+Qs+2JdXgIElnOT/aDqtRtriDmLlSbtdE8n3ZbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "8.17.1", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.2", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^4.0.0" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@angular/cli/node_modules/@angular-devkit/schematics": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.15.tgz", - "integrity": "sha512-kNOJ+3vekJJCQKWihNmxBkarJzNW09kP5a9E1SRNiQVNOUEeSwcRR0qYotM65nx821gNzjjhJXnAZ8OazWldrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "19.2.15", - "jsonc-parser": "3.3.1", - "magic-string": "0.30.17", - "ora": "5.4.1", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular/cli/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@angular/cli/node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" + "rollup": "dist/bin/rollup" }, - "peerDependencies": { - "ajv": "^8.0.0" + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.52.5", + "@rollup/rollup-android-arm64": "4.52.5", + "@rollup/rollup-darwin-arm64": "4.52.5", + "@rollup/rollup-darwin-x64": "4.52.5", + "@rollup/rollup-freebsd-arm64": "4.52.5", + "@rollup/rollup-freebsd-x64": "4.52.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.5", + "@rollup/rollup-linux-arm-musleabihf": "4.52.5", + "@rollup/rollup-linux-arm64-gnu": "4.52.5", + "@rollup/rollup-linux-arm64-musl": "4.52.5", + "@rollup/rollup-linux-loong64-gnu": "4.52.5", + "@rollup/rollup-linux-ppc64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-musl": "4.52.5", + "@rollup/rollup-linux-s390x-gnu": "4.52.5", + "@rollup/rollup-linux-x64-gnu": "4.52.5", + "@rollup/rollup-linux-x64-musl": "4.52.5", + "@rollup/rollup-openharmony-arm64": "4.52.5", + "@rollup/rollup-win32-arm64-msvc": "4.52.5", + "@rollup/rollup-win32-ia32-msvc": "4.52.5", + "@rollup/rollup-win32-x64-gnu": "4.52.5", + "@rollup/rollup-win32-x64-msvc": "4.52.5", + "fsevents": "~2.3.2" } }, - "node_modules/@angular/cli/node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", - "dev": true, + "node_modules/@angular/cdk": { + "version": "19.2.19", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-19.2.19.tgz", + "integrity": "sha512-PCpJagurPBqciqcq4Z8+3OtKLb7rSl4w/qBJoIMua8CgnrjvA1i+SWawhdtfI1zlY8FSwhzLwXV0CmWWfFzQPg==", "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" + "parse5": "^7.1.2", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": "^19.0.0 || ^20.0.0", + "@angular/core": "^19.0.0 || ^20.0.0", + "rxjs": "^6.5.3 || ^7.4.0" } }, - "node_modules/@angular/cli/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "node_modules/@angular/cli": { + "version": "19.2.18", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-19.2.18.tgz", + "integrity": "sha512-TwqS0+4k28EepFNRalQJs4qj4axLCfFSJJAWP+mZlVUyCgYL6L7Kw851f7tfG6wTuSV1xI8ysJtRtycAEqooJA==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "tslib": "^2.1.0" + "@angular-devkit/architect": "0.1902.18", + "@angular-devkit/core": "19.2.18", + "@angular-devkit/schematics": "19.2.18", + "@inquirer/prompts": "7.3.2", + "@listr2/prompt-adapter-inquirer": "2.0.18", + "@schematics/angular": "19.2.18", + "@yarnpkg/lockfile": "1.1.0", + "ini": "5.0.0", + "jsonc-parser": "3.3.1", + "listr2": "8.2.5", + "npm-package-arg": "12.0.2", + "npm-pick-manifest": "10.0.0", + "pacote": "20.0.0", + "resolve": "1.22.10", + "semver": "7.7.1", + "symbol-observable": "4.0.0", + "yargs": "17.7.2" + }, + "bin": { + "ng": "bin/ng.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" } }, "node_modules/@angular/common": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-19.2.14.tgz", - "integrity": "sha512-NcNklcuyqaTjOVGf7aru8APX9mjsnZ01gFZrn47BxHozhaR0EMRrotYQTdi8YdVjPkeYFYanVntSLfhyobq/jg==", + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-19.2.15.tgz", + "integrity": "sha512-aVa/ctBYH/4qgA7r4sS7TV+/DzRYmcS+3d6l89pNKUXkI8gpmsd+r3FjccaemX4Wqru1QOrMvC+i+e7IBIVv0g==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1565,14 +1313,14 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "19.2.14", + "@angular/core": "19.2.15", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-19.2.14.tgz", - "integrity": "sha512-ZqJDYOdhgKpVGNq3+n/Gbxma8DVYElDsoRe0tvNtjkWBVdaOxdZZUqmJ3kdCBsqD/aqTRvRBu0KGo9s2fCChkA==", + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-19.2.15.tgz", + "integrity": "sha512-hMHZU6/03xG0tbPDIm1hbVSTFLnRkGYfh+xdBwUMnIFYYTS0QJ2hdPfEZKCJIXm+fz9IAI5MPdDTfeyp0sgaHQ==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1582,9 +1330,9 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-19.2.14.tgz", - "integrity": "sha512-e9/h86ETjoIK2yTLE9aUeMCKujdg/du2pq7run/aINjop4RtnNOw+ZlSTUa6R65lP5CVwDup1kPytpAoifw8cA==", + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-19.2.15.tgz", + "integrity": "sha512-4r5tvGA2Ok3o8wROZBkF9qNKS7L0AEpdBIkAVJbLw2rBY2SlyycFIRYyV2+D1lJ1jq/f9U7uN6oon0MjTvNYkA==", "dev": true, "license": "MIT", "dependencies": { @@ -1606,7 +1354,7 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/compiler": "19.2.14", + "@angular/compiler": "19.2.15", "typescript": ">=5.5 <5.9" } }, @@ -1658,40 +1406,10 @@ "semver": "bin/semver.js" } }, - "node_modules/@angular/compiler-cli/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@angular/compiler-cli/node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular/core": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-19.2.14.tgz", - "integrity": "sha512-EVErpW9tGqJ/wNcAN3G/ErH8pHCJ8mM1E6bsJ8UJIpDTZkpqqYjBMtZS9YWH5n3KwUd1tAkAB2w8FK125AjDUQ==", + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-19.2.15.tgz", + "integrity": "sha512-PxhzCwwm23N4Mq6oV7UPoYiJF4r6FzGhRSxOBBlEp322k7zEQbIxd/XO6F3eoG73qC1UsOXMYYv6GnQpx42y3A==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1705,9 +1423,9 @@ } }, "node_modules/@angular/forms": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-19.2.14.tgz", - "integrity": "sha512-hWtDOj2B0AuRTf+nkMJeodnFpDpmEK9OIhIv1YxcRe73ooaxrIdjgugkElO8I9Tj0E4/7m117ezhWDUkbqm1zA==", + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-19.2.15.tgz", + "integrity": "sha512-pZDElcYPmNzPxvWJpZQCIizsNApDIfk9xLJE4I8hzLISfWGbQvfjuuarDAuQZEXudeLXoDOstDXkDja40muLGg==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1716,16 +1434,16 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "19.2.14", - "@angular/core": "19.2.14", - "@angular/platform-browser": "19.2.14", + "@angular/common": "19.2.15", + "@angular/core": "19.2.15", + "@angular/platform-browser": "19.2.15", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/platform-browser": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-19.2.14.tgz", - "integrity": "sha512-hzkT5nmA64oVBQl6PRjdL4dIFT1n7lfM9rm5cAoS+6LUUKRgiE2d421Kpn/Hz3jaCJfo+calMIdtSMIfUJBmww==", + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-19.2.15.tgz", + "integrity": "sha512-OelQ6weCjon8kZD8kcqNzwugvZJurjS3uMJCwsA2vXmP/3zJ31SWtNqE2zLT1R2csVuwnp0h+nRMgq+pINU7Rg==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1734,9 +1452,9 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/animations": "19.2.14", - "@angular/common": "19.2.14", - "@angular/core": "19.2.14" + "@angular/animations": "19.2.15", + "@angular/common": "19.2.15", + "@angular/core": "19.2.15" }, "peerDependenciesMeta": { "@angular/animations": { @@ -1745,9 +1463,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-19.2.14.tgz", - "integrity": "sha512-Hfz0z1KDQmIdnFXVFCwCPykuIsHPkr1uW2aY396eARwZ6PK8i0Aadcm1ZOnpd3MR1bMyDrJo30VRS5kx89QWvA==", + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-19.2.15.tgz", + "integrity": "sha512-dKy0SS395FCh8cW9AQ8nf4Wn3XlONaH7z50T1bGxm3eOoRqjxJYyIeIlEbDdJakMz4QPR3dGr81HleZd8TJumQ==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1756,16 +1474,16 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "19.2.14", - "@angular/compiler": "19.2.14", - "@angular/core": "19.2.14", - "@angular/platform-browser": "19.2.14" + "@angular/common": "19.2.15", + "@angular/compiler": "19.2.15", + "@angular/core": "19.2.15", + "@angular/platform-browser": "19.2.15" } }, "node_modules/@angular/router": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-19.2.14.tgz", - "integrity": "sha512-cBTWY9Jx7YhbmDYDb7Hqz4Q7UNIMlKTkdKToJd2pbhIXyoS+kHVQrySmyca+jgvYMjWnIjsAEa3dpje12D4mFw==", + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-19.2.15.tgz", + "integrity": "sha512-0TM1D8S7RQ00drKy7hA/ZLBY14dUBqFBgm06djcNcOjNzVAtgkeV0i+0Smq9tCC7UsGKdpZu4RgfYjHATBNlTQ==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1774,16 +1492,16 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "19.2.14", - "@angular/core": "19.2.14", - "@angular/platform-browser": "19.2.14", + "@angular/common": "19.2.15", + "@angular/core": "19.2.15", + "@angular/platform-browser": "19.2.15", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/service-worker": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-19.2.14.tgz", - "integrity": "sha512-ajH4kjsuzDvJNxnG18y8N47R0avXFKwOeLszoiirlr5160C+k4HmQvIbzcCjD5liW0OkmxJN1cMW6KdilP8/2w==", + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-19.2.15.tgz", + "integrity": "sha512-H40T8ni4Inx3tNinoQvcEmDsgFErjfzEWnJpoAonDQkzarlu1Qr8vBgv+DX+KzuMKZ3xtsWW9vFnAI4/DilnDw==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1795,7 +1513,7 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "19.2.14", + "@angular/core": "19.2.15", "rxjs": "^6.5.3 || ^7.4.0" } }, @@ -1815,9 +1533,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", - "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz", + "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", "dev": true, "license": "MIT", "engines": { @@ -2233,27 +1951,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.3.tgz", - "integrity": "sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.27.2", - "@babel/types": "^7.28.2" + "@babel/types": "^7.28.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.3.tgz", - "integrity": "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", + "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.28.2" + "@babel/types": "^7.28.4" }, "bin": { "parser": "bin/babel-parser.js" @@ -2477,9 +2195,9 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.0.tgz", - "integrity": "sha512-gKKnwjpdx5sER/wl0WN0efUBFzF/56YZO0RJrSYP4CljXnP31ByY7fol89AzomdlLNzI36AvOTmYHsnZTCkq8Q==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.4.tgz", + "integrity": "sha512-1yxmvN0MJHOhPVmAsmoW5liWwoILobu/d/ShymZmj867bAdxGbehIrew1DuLpw2Ukv+qDSSPQdYW1dLNE7t11A==", "dev": true, "license": "MIT", "dependencies": { @@ -2527,9 +2245,9 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.3.tgz", - "integrity": "sha512-DoEWC5SuxuARF2KdKmGUq3ghfPMO6ZzR12Dnp5gubwbeWJo4dbNWXJPVlwvh4Zlq6Z7YVvL8VFxeSOJgjsx4Sg==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", + "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", "dev": true, "license": "MIT", "dependencies": { @@ -2538,7 +2256,7 @@ "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", - "@babel/traverse": "^7.28.3" + "@babel/traverse": "^7.28.4" }, "engines": { "node": ">=6.9.0" @@ -2927,9 +2645,9 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.0.tgz", - "integrity": "sha512-9VNGikXxzu5eCiQjdE4IZn8sb9q7Xsk5EXLDBKUYg1e/Tve8/05+KJEtcxGxAgCY5t/BpKQM+JEL/yT4tvgiUA==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz", + "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==", "dev": true, "license": "MIT", "dependencies": { @@ -2937,7 +2655,7 @@ "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.0", "@babel/plugin-transform-parameters": "^7.27.7", - "@babel/traverse": "^7.28.0" + "@babel/traverse": "^7.28.4" }, "engines": { "node": ">=6.9.0" @@ -3077,9 +2795,9 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.3.tgz", - "integrity": "sha512-K3/M/a4+ESb5LEldjQb+XSrpY0nF+ZBFlTCbSnKaYAMfD8v33O6PMs4uYnOk19HlcsI8WMu3McdFPTiQHF/1/A==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz", + "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==", "dev": true, "license": "MIT", "dependencies": { @@ -3442,18 +3160,18 @@ } }, "node_modules/@babel/traverse": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.3.tgz", - "integrity": "sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", + "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.3", + "@babel/parser": "^7.28.4", "@babel/template": "^7.27.2", - "@babel/types": "^7.28.2", + "@babel/types": "^7.28.4", "debug": "^4.3.1" }, "engines": { @@ -3478,9 +3196,9 @@ } }, "node_modules/@babel/types": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", - "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", + "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", "dev": true, "license": "MIT", "dependencies": { @@ -3491,6 +3209,76 @@ "node": ">=6.9.0" } }, + "node_modules/@cacheable/memoize": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@cacheable/memoize/-/memoize-2.0.3.tgz", + "integrity": "sha512-hl9wfQgpiydhQEIv7fkjEzTGE+tcosCXLKFDO707wYJ/78FVOlowb36djex5GdbSyeHnG62pomYLMuV/OT8Pbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cacheable/utils": "^2.0.3" + } + }, + "node_modules/@cacheable/memory": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.0.3.tgz", + "integrity": "sha512-R3UKy/CKOyb1LZG/VRCTMcpiMDyLH7SH3JrraRdK6kf3GweWCOU3sgvE13W3TiDRbxnDKylzKJvhUAvWl9LQOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cacheable/memoize": "^2.0.3", + "@cacheable/utils": "^2.0.3", + "@keyv/bigmap": "^1.0.2", + "hookified": "^1.12.1", + "keyv": "^5.5.3" + } + }, + "node_modules/@cacheable/memory/node_modules/@keyv/bigmap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@keyv/bigmap/-/bigmap-1.1.0.tgz", + "integrity": "sha512-MX7XIUNwVRK+hjZcAbNJ0Z8DREo+Weu9vinBOjGU1thEi9F6vPhICzBbk4CCf3eEefKRz7n6TfZXwUFZTSgj8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "hookified": "^1.12.2" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "keyv": "^5.5.3" + } + }, + "node_modules/@cacheable/memory/node_modules/keyv": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.3.tgz", + "integrity": "sha512-h0Un1ieD+HUrzBH6dJXhod3ifSghk5Hw/2Y4/KHBziPlZecrFyE9YOTPU6eOs0V9pYl8gOs86fkr/KN8lUX39A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, + "node_modules/@cacheable/utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.1.0.tgz", + "integrity": "sha512-ZdxfOiaarMqMj+H7qwlt5EBKWaeGihSYVHdQv5lUsbn8MJJOTW82OIwirQ39U5tMZkNvy3bQE+ryzC+xTAb9/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "keyv": "^5.5.3" + } + }, + "node_modules/@cacheable/utils/node_modules/keyv": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.3.tgz", + "integrity": "sha512-h0Un1ieD+HUrzBH6dJXhod3ifSghk5Hw/2Y4/KHBziPlZecrFyE9YOTPU6eOs0V9pYl8gOs86fkr/KN8lUX39A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -3613,9 +3401,9 @@ } }, "node_modules/@emnapi/core": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.5.0.tgz", - "integrity": "sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.6.0.tgz", + "integrity": "sha512-zq/ay+9fNIJJtJiZxdTnXS20PllcYMX3OE23ESc4HK/bdYu3cOWYVhsOhVnXALfU/uqJIxn5NBPd9z4v+SfoSg==", "dev": true, "license": "MIT", "optional": true, @@ -3625,9 +3413,9 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.5.0.tgz", - "integrity": "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.6.0.tgz", + "integrity": "sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA==", "dev": true, "license": "MIT", "optional": true, @@ -4071,9 +3859,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.8.0.tgz", - "integrity": "sha512-MJQFqrZgcW0UNYLGOuQpey/oTN59vyWwplvCGZztn1cKz9agZPPYpJB7h2OMmuu7VLqkvEjN8feFZJmxNF9D+Q==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", "dev": true, "license": "MIT", "dependencies": { @@ -4090,9 +3878,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, "license": "MIT", "engines": { @@ -4100,14 +3888,14 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", - "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", "dev": true, "license": "Apache-2.0", "peer": true, "dependencies": { - "@eslint/object-schema": "^2.1.6", + "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.2" }, @@ -4142,20 +3930,23 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz", - "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.1.tgz", + "integrity": "sha512-csZAzkNhsgwb0I/UAV6/RGFTbiakPCf0ZrGmrIxQpYvGZ00PhTkSnyKNolphgIvmnJeGw6rcGVEXfTzUnFuEvw==", "dev": true, "license": "Apache-2.0", "peer": true, + "dependencies": { + "@eslint/core": "^0.16.0" + }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/core": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", - "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz", + "integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==", "dev": true, "license": "Apache-2.0", "peer": true, @@ -4255,9 +4046,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.34.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.34.0.tgz", - "integrity": "sha512-EoyvqQnBNsV1CWaEJ559rxXL4c8V92gxirbawSmVUOWXlsRxxQXl6LmCpdUblgxgSkDIqKnhzba2SjRTI/A5Rw==", + "version": "9.38.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.38.0.tgz", + "integrity": "sha512-UZ1VpFvXf9J06YG9xQBdnzU+kthors6KjhMAl6f4gH4usHyh31rUf2DLGInT8RFYIReYXNSydgPY0V2LuWgl7A==", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4267,9 +4058,9 @@ } }, "node_modules/@eslint/object-schema": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", - "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", "dev": true, "license": "Apache-2.0", "peer": true, @@ -4278,14 +4069,14 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", - "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.0.tgz", + "integrity": "sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==", "dev": true, "license": "Apache-2.0", "peer": true, "dependencies": { - "@eslint/core": "^0.15.2", + "@eslint/core": "^0.16.0", "levn": "^0.4.1" }, "engines": { @@ -4348,10 +4139,20 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@img/colour": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", + "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/@img/sharp-darwin-arm64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.3.tgz", - "integrity": "sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==", + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.4.tgz", + "integrity": "sha512-sitdlPzDVyvmINUdJle3TNHl+AG9QcwiAMsXmccqsCOMZNIdW2/7S26w0LyU8euiLVzFBL3dXPwVCq/ODnf2vA==", "cpu": [ "arm64" ], @@ -4368,13 +4169,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.2.0" + "@img/sharp-libvips-darwin-arm64": "1.2.3" } }, "node_modules/@img/sharp-darwin-x64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.3.tgz", - "integrity": "sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA==", + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.4.tgz", + "integrity": "sha512-rZheupWIoa3+SOdF/IcUe1ah4ZDpKBGWcsPX6MT0lYniH9micvIU7HQkYTfrx5Xi8u+YqwLtxC/3vl8TQN6rMg==", "cpu": [ "x64" ], @@ -4391,13 +4192,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.2.0" + "@img/sharp-libvips-darwin-x64": "1.2.3" } }, "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.0.tgz", - "integrity": "sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.3.tgz", + "integrity": "sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw==", "cpu": [ "arm64" ], @@ -4412,9 +4213,9 @@ } }, "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.0.tgz", - "integrity": "sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.3.tgz", + "integrity": "sha512-Ju+g2xn1E2AKO6YBhxjj+ACcsPQRHT0bhpglxcEf+3uyPY+/gL8veniKoo96335ZaPo03bdDXMv0t+BBFAbmRA==", "cpu": [ "x64" ], @@ -4429,9 +4230,9 @@ } }, "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.0.tgz", - "integrity": "sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.3.tgz", + "integrity": "sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA==", "cpu": [ "arm" ], @@ -4446,9 +4247,9 @@ } }, "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.0.tgz", - "integrity": "sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.3.tgz", + "integrity": "sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ==", "cpu": [ "arm64" ], @@ -4463,9 +4264,9 @@ } }, "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.0.tgz", - "integrity": "sha512-Xod/7KaDDHkYu2phxxfeEPXfVXFKx70EAFZ0qyUdOjCcxbjqyJOEUpDe6RIyaunGxT34Anf9ue/wuWOqBW2WcQ==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.3.tgz", + "integrity": "sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg==", "cpu": [ "ppc64" ], @@ -4480,9 +4281,9 @@ } }, "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.0.tgz", - "integrity": "sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.3.tgz", + "integrity": "sha512-RgWrs/gVU7f+K7P+KeHFaBAJlNkD1nIZuVXdQv6S+fNA6syCcoboNjsV2Pou7zNlVdNQoQUpQTk8SWDHUA3y/w==", "cpu": [ "s390x" ], @@ -4497,9 +4298,9 @@ } }, "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.0.tgz", - "integrity": "sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.3.tgz", + "integrity": "sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg==", "cpu": [ "x64" ], @@ -4514,9 +4315,9 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.0.tgz", - "integrity": "sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.3.tgz", + "integrity": "sha512-F9q83RZ8yaCwENw1GieztSfj5msz7GGykG/BA+MOUefvER69K/ubgFHNeSyUu64amHIYKGDs4sRCMzXVj8sEyw==", "cpu": [ "arm64" ], @@ -4531,9 +4332,9 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.0.tgz", - "integrity": "sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.3.tgz", + "integrity": "sha512-U5PUY5jbc45ANM6tSJpsgqmBF/VsL6LnxJmIf11kB7J5DctHgqm0SkuXzVWtIY90GnJxKnC/JT251TDnk1fu/g==", "cpu": [ "x64" ], @@ -4548,9 +4349,9 @@ } }, "node_modules/@img/sharp-linux-arm": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.3.tgz", - "integrity": "sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A==", + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.4.tgz", + "integrity": "sha512-Xyam4mlqM0KkTHYVSuc6wXRmM7LGN0P12li03jAnZ3EJWZqj83+hi8Y9UxZUbxsgsK1qOEwg7O0Bc0LjqQVtxA==", "cpu": [ "arm" ], @@ -4567,13 +4368,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.2.0" + "@img/sharp-libvips-linux-arm": "1.2.3" } }, "node_modules/@img/sharp-linux-arm64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.3.tgz", - "integrity": "sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA==", + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.4.tgz", + "integrity": "sha512-YXU1F/mN/Wu786tl72CyJjP/Ngl8mGHN1hST4BGl+hiW5jhCnV2uRVTNOcaYPs73NeT/H8Upm3y9582JVuZHrQ==", "cpu": [ "arm64" ], @@ -4590,13 +4391,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.2.0" + "@img/sharp-libvips-linux-arm64": "1.2.3" } }, "node_modules/@img/sharp-linux-ppc64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.3.tgz", - "integrity": "sha512-GLtbLQMCNC5nxuImPR2+RgrviwKwVql28FWZIW1zWruy6zLgA5/x2ZXk3mxj58X/tszVF69KK0Is83V8YgWhLA==", + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.4.tgz", + "integrity": "sha512-F4PDtF4Cy8L8hXA2p3TO6s4aDt93v+LKmpcYFLAVdkkD3hSxZzee0rh6/+94FpAynsuMpLX5h+LRsSG3rIciUQ==", "cpu": [ "ppc64" ], @@ -4613,13 +4414,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.2.0" + "@img/sharp-libvips-linux-ppc64": "1.2.3" } }, "node_modules/@img/sharp-linux-s390x": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.3.tgz", - "integrity": "sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ==", + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.4.tgz", + "integrity": "sha512-qVrZKE9Bsnzy+myf7lFKvng6bQzhNUAYcVORq2P7bDlvmF6u2sCmK2KyEQEBdYk+u3T01pVsPrkj943T1aJAsw==", "cpu": [ "s390x" ], @@ -4636,13 +4437,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.2.0" + "@img/sharp-libvips-linux-s390x": "1.2.3" } }, "node_modules/@img/sharp-linux-x64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.3.tgz", - "integrity": "sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ==", + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.4.tgz", + "integrity": "sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A==", "cpu": [ "x64" ], @@ -4659,13 +4460,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.2.0" + "@img/sharp-libvips-linux-x64": "1.2.3" } }, "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.3.tgz", - "integrity": "sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ==", + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.4.tgz", + "integrity": "sha512-8hDVvW9eu4yHWnjaOOR8kHVrew1iIX+MUgwxSuH2XyYeNRtLUe4VNioSqbNkB7ZYQJj9rUTT4PyRscyk2PXFKA==", "cpu": [ "arm64" ], @@ -4682,13 +4483,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.2.0" + "@img/sharp-libvips-linuxmusl-arm64": "1.2.3" } }, "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.3.tgz", - "integrity": "sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ==", + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.4.tgz", + "integrity": "sha512-lU0aA5L8QTlfKjpDCEFOZsTYGn3AEiO6db8W5aQDxj0nQkVrZWmN3ZP9sYKWJdtq3PWPhUNlqehWyXpYDcI9Sg==", "cpu": [ "x64" ], @@ -4705,13 +4506,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.2.0" + "@img/sharp-libvips-linuxmusl-x64": "1.2.3" } }, "node_modules/@img/sharp-wasm32": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.3.tgz", - "integrity": "sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg==", + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.4.tgz", + "integrity": "sha512-33QL6ZO/qpRyG7woB/HUALz28WnTMI2W1jgX3Nu2bypqLIKx/QKMILLJzJjI+SIbvXdG9fUnmrxR7vbi1sTBeA==", "cpu": [ "wasm32" ], @@ -4719,7 +4520,7 @@ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", "optional": true, "dependencies": { - "@emnapi/runtime": "^1.4.4" + "@emnapi/runtime": "^1.5.0" }, "engines": { "node": "^18.17.0 || ^20.3.0 || >=21.0.0" @@ -4729,9 +4530,9 @@ } }, "node_modules/@img/sharp-win32-arm64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.3.tgz", - "integrity": "sha512-MjnHPnbqMXNC2UgeLJtX4XqoVHHlZNd+nPt1kRPmj63wURegwBhZlApELdtxM2OIZDRv/DFtLcNhVbd1z8GYXQ==", + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.4.tgz", + "integrity": "sha512-2Q250do/5WXTwxW3zjsEuMSv5sUU4Tq9VThWKlU2EYLm4MB7ZeMwF+SFJutldYODXF6jzc6YEOC+VfX0SZQPqA==", "cpu": [ "arm64" ], @@ -4749,9 +4550,9 @@ } }, "node_modules/@img/sharp-win32-ia32": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.3.tgz", - "integrity": "sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw==", + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.4.tgz", + "integrity": "sha512-3ZeLue5V82dT92CNL6rsal6I2weKw1cYu+rGKm8fOCCtJTR2gYeUfY3FqUnIJsMUPIH68oS5jmZ0NiJ508YpEw==", "cpu": [ "ia32" ], @@ -4769,9 +4570,9 @@ } }, "node_modules/@img/sharp-win32-x64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.3.tgz", - "integrity": "sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g==", + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.4.tgz", + "integrity": "sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig==", "cpu": [ "x64" ], @@ -4788,17 +4589,27 @@ "url": "https://opencollective.com/libvips" } }, + "node_modules/@inquirer/ansi": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.1.tgz", + "integrity": "sha512-yqq0aJW/5XPhi5xOAL1xRCpe1eh8UFVgYFpFsjEqmIR8rKLyP+HINvFXwUaxYICflJrVlxnp7lLN6As735kVpw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/@inquirer/checkbox": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.2.2.tgz", - "integrity": "sha512-E+KExNurKcUJJdxmjglTl141EwxWyAHplvsYJQgSwXf8qiNWkTxTuCCqmhFEmbIXd4zLaGMfQFJ6WrZ7fSeV3g==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.0.tgz", + "integrity": "sha512-5+Q3PKH35YsnoPTh75LucALdAxom6xh5D1oeY561x4cqBuH24ZFVyFREPe14xgnrtmGu3EEt1dIi60wRVSnGCw==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.2.0", - "@inquirer/figures": "^1.0.13", - "@inquirer/type": "^3.0.8", - "ansi-escapes": "^4.3.2", + "@inquirer/ansi": "^1.0.1", + "@inquirer/core": "^10.3.0", + "@inquirer/figures": "^1.0.14", + "@inquirer/type": "^3.0.9", "yoctocolors-cjs": "^2.1.2" }, "engines": { @@ -4836,15 +4647,15 @@ } }, "node_modules/@inquirer/core": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.2.0.tgz", - "integrity": "sha512-NyDSjPqhSvpZEMZrLCYUquWNl+XC/moEcVFqS55IEYIYsY0a1cUCevSqk7ctOlnm/RaSBU5psFryNlxcmGrjaA==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.0.tgz", + "integrity": "sha512-Uv2aPPPSK5jeCplQmQ9xadnFx2Zhj9b5Dj7bU6ZeCdDNNY11nhYy4btcSdtDguHqCT2h5oNeQTcUNSGGLA7NTA==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/figures": "^1.0.13", - "@inquirer/type": "^3.0.8", - "ansi-escapes": "^4.3.2", + "@inquirer/ansi": "^1.0.1", + "@inquirer/figures": "^1.0.14", + "@inquirer/type": "^3.0.9", "cli-width": "^4.1.0", "mute-stream": "^2.0.0", "signal-exit": "^4.1.0", @@ -4864,15 +4675,15 @@ } }, "node_modules/@inquirer/editor": { - "version": "4.2.18", - "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.18.tgz", - "integrity": "sha512-yeQN3AXjCm7+Hmq5L6Dm2wEDeBRdAZuyZ4I7tWSSanbxDzqM0KqzoDbKM7p4ebllAYdoQuPJS6N71/3L281i6w==", + "version": "4.2.21", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.21.tgz", + "integrity": "sha512-MjtjOGjr0Kh4BciaFShYpZ1s9400idOdvQ5D7u7lE6VztPFoyLcVNE5dXBmEEIQq5zi4B9h2kU+q7AVBxJMAkQ==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.2.0", - "@inquirer/external-editor": "^1.0.1", - "@inquirer/type": "^3.0.8" + "@inquirer/core": "^10.3.0", + "@inquirer/external-editor": "^1.0.2", + "@inquirer/type": "^3.0.9" }, "engines": { "node": ">=18" @@ -4887,14 +4698,14 @@ } }, "node_modules/@inquirer/expand": { - "version": "4.0.18", - "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.18.tgz", - "integrity": "sha512-xUjteYtavH7HwDMzq4Cn2X4Qsh5NozoDHCJTdoXg9HfZ4w3R6mxV1B9tL7DGJX2eq/zqtsFjhm0/RJIMGlh3ag==", + "version": "4.0.21", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.21.tgz", + "integrity": "sha512-+mScLhIcbPFmuvU3tAGBed78XvYHSvCl6dBiYMlzCLhpr0bzGzd8tfivMMeqND6XZiaZ1tgusbUHJEfc6YzOdA==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.2.0", - "@inquirer/type": "^3.0.8", + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9", "yoctocolors-cjs": "^2.1.2" }, "engines": { @@ -4910,14 +4721,14 @@ } }, "node_modules/@inquirer/external-editor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.1.tgz", - "integrity": "sha512-Oau4yL24d2B5IL4ma4UpbQigkVhzPDXLoqy1ggK4gnHg/stmkffJE4oOXHXF3uz0UEpywG68KcyXsyYpA1Re/Q==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.2.tgz", + "integrity": "sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==", "dev": true, "license": "MIT", "dependencies": { "chardet": "^2.1.0", - "iconv-lite": "^0.6.3" + "iconv-lite": "^0.7.0" }, "engines": { "node": ">=18" @@ -4932,9 +4743,9 @@ } }, "node_modules/@inquirer/figures": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.13.tgz", - "integrity": "sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==", + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.14.tgz", + "integrity": "sha512-DbFgdt+9/OZYFM+19dbpXOSeAstPy884FPy1KjDu4anWwymZeOYhMY1mdFri172htv6mvc/uvIAAi7b7tvjJBQ==", "dev": true, "license": "MIT", "engines": { @@ -4942,14 +4753,14 @@ } }, "node_modules/@inquirer/input": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.2.2.tgz", - "integrity": "sha512-hqOvBZj/MhQCpHUuD3MVq18SSoDNHy7wEnQ8mtvs71K8OPZVXJinOzcvQna33dNYLYE4LkA9BlhAhK6MJcsVbw==", + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.2.5.tgz", + "integrity": "sha512-7GoWev7P6s7t0oJbenH0eQ0ThNdDJbEAEtVt9vsrYZ9FulIokvd823yLyhQlWHJPGce1wzP53ttfdCZmonMHyA==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.2.0", - "@inquirer/type": "^3.0.8" + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9" }, "engines": { "node": ">=18" @@ -4964,14 +4775,14 @@ } }, "node_modules/@inquirer/number": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.18.tgz", - "integrity": "sha512-7exgBm52WXZRczsydCVftozFTrrwbG5ySE0GqUd2zLNSBXyIucs2Wnm7ZKLe/aUu6NUg9dg7Q80QIHCdZJiY4A==", + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.21.tgz", + "integrity": "sha512-5QWs0KGaNMlhbdhOSCFfKsW+/dcAVC2g4wT/z2MCiZM47uLgatC5N20kpkDQf7dHx+XFct/MJvvNGy6aYJn4Pw==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.2.0", - "@inquirer/type": "^3.0.8" + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9" }, "engines": { "node": ">=18" @@ -4986,15 +4797,15 @@ } }, "node_modules/@inquirer/password": { - "version": "4.0.18", - "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.18.tgz", - "integrity": "sha512-zXvzAGxPQTNk/SbT3carAD4Iqi6A2JS2qtcqQjsL22uvD+JfQzUrDEtPjLL7PLn8zlSNyPdY02IiQjzoL9TStA==", + "version": "4.0.21", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.21.tgz", + "integrity": "sha512-xxeW1V5SbNFNig2pLfetsDb0svWlKuhmr7MPJZMYuDnCTkpVBI+X/doudg4pznc1/U+yYmWFFOi4hNvGgUo7EA==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.2.0", - "@inquirer/type": "^3.0.8", - "ansi-escapes": "^4.3.2" + "@inquirer/ansi": "^1.0.1", + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9" }, "engines": { "node": ">=18" @@ -5039,14 +4850,14 @@ } }, "node_modules/@inquirer/rawlist": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.6.tgz", - "integrity": "sha512-KOZqa3QNr3f0pMnufzL7K+nweFFCCBs6LCXZzXDrVGTyssjLeudn5ySktZYv1XiSqobyHRYYK0c6QsOxJEhXKA==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.9.tgz", + "integrity": "sha512-AWpxB7MuJrRiSfTKGJ7Y68imYt8P9N3Gaa7ySdkFj1iWjr6WfbGAhdZvw/UnhFXTHITJzxGUI9k8IX7akAEBCg==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.2.0", - "@inquirer/type": "^3.0.8", + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9", "yoctocolors-cjs": "^2.1.2" }, "engines": { @@ -5062,15 +4873,15 @@ } }, "node_modules/@inquirer/search": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.1.1.tgz", - "integrity": "sha512-TkMUY+A2p2EYVY3GCTItYGvqT6LiLzHBnqsU1rJbrpXUijFfM6zvUx0R4civofVwFCmJZcKqOVwwWAjplKkhxA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.0.tgz", + "integrity": "sha512-a5SzB/qrXafDX1Z4AZW3CsVoiNxcIYCzYP7r9RzrfMpaLpB+yWi5U8BWagZyLmwR0pKbbL5umnGRd0RzGVI8bQ==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.2.0", - "@inquirer/figures": "^1.0.13", - "@inquirer/type": "^3.0.8", + "@inquirer/core": "^10.3.0", + "@inquirer/figures": "^1.0.14", + "@inquirer/type": "^3.0.9", "yoctocolors-cjs": "^2.1.2" }, "engines": { @@ -5086,16 +4897,16 @@ } }, "node_modules/@inquirer/select": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.3.2.tgz", - "integrity": "sha512-nwous24r31M+WyDEHV+qckXkepvihxhnyIaod2MG7eCE6G0Zm/HUF6jgN8GXgf4U7AU6SLseKdanY195cwvU6w==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.0.tgz", + "integrity": "sha512-kaC3FHsJZvVyIjYBs5Ih8y8Bj4P/QItQWrZW22WJax7zTN+ZPXVGuOM55vzbdCP9zKUiBd9iEJVdesujfF+cAA==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.2.0", - "@inquirer/figures": "^1.0.13", - "@inquirer/type": "^3.0.8", - "ansi-escapes": "^4.3.2", + "@inquirer/ansi": "^1.0.1", + "@inquirer/core": "^10.3.0", + "@inquirer/figures": "^1.0.14", + "@inquirer/type": "^3.0.9", "yoctocolors-cjs": "^2.1.2" }, "engines": { @@ -5111,9 +4922,9 @@ } }, "node_modules/@inquirer/type": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.8.tgz", - "integrity": "sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.9.tgz", + "integrity": "sha512-QPaNt/nmE2bLGQa9b7wwyRJoLZ7pN6rcyXvzU0YCmivmJyq1BVo94G98tStRWkoD1RgDX5C+dPlhhHzNdu/W/w==", "dev": true, "license": "MIT", "engines": { @@ -5170,9 +4981,9 @@ } }, "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, "license": "MIT", "engines": { @@ -5288,9 +5099,9 @@ "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.30", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz", - "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", "dependencies": { @@ -5316,9 +5127,9 @@ } }, "node_modules/@jsonjoy.com/buffers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.0.0.tgz", - "integrity": "sha512-NDigYR3PHqCnQLXYyoLbnEdzMMvzeiCWo1KOut7Q0CoIqg9tUAPKJ1iq/2nFhc5kZtexzutNY0LFjdwWL3Dw3Q==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -5350,19 +5161,20 @@ } }, "node_modules/@jsonjoy.com/json-pack": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.11.0.tgz", - "integrity": "sha512-nLqSTAYwpk+5ZQIoVp7pfd/oSKNWlEdvTq2LzVA4r2wtWZg6v+5u0VgBOaDJuUfNOuw/4Ysq6glN5QKSrOCgrA==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz", + "integrity": "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==", "dev": true, "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/base64": "^1.1.2", - "@jsonjoy.com/buffers": "^1.0.0", + "@jsonjoy.com/buffers": "^1.2.0", "@jsonjoy.com/codegen": "^1.0.0", - "@jsonjoy.com/json-pointer": "^1.0.1", + "@jsonjoy.com/json-pointer": "^1.0.2", "@jsonjoy.com/util": "^1.9.0", "hyperdyperid": "^1.2.0", - "thingies": "^2.5.0" + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" }, "engines": { "node": ">=10.0" @@ -5418,9 +5230,9 @@ } }, "node_modules/@keyv/serialize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.0.tgz", - "integrity": "sha512-RlDgexML7Z63Q8BSaqhXdCYNBy/JQnqYIwxofUrNLGCblOMHp+xux2Q8nLMLlPpgHQPoU0Do8Z6btCpRBEqZ8g==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==", "dev": true, "license": "MIT" }, @@ -5555,9 +5367,9 @@ ] }, "node_modules/@maskito/angular": { - "version": "3.10.3", - "resolved": "https://registry.npmjs.org/@maskito/angular/-/angular-3.10.3.tgz", - "integrity": "sha512-Wu64iLuuMZH/3fXgQSj15i/XRDcGdxIYY1eoq+zEUX0JkN+f1DLYzS4QVUMz/APNb7mnpnmNP0omr0feEWj+Kg==", + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/@maskito/angular/-/angular-3.11.1.tgz", + "integrity": "sha512-+OZzbRJj/9fOGhgPr0xYctSHe/Ngahip3VdNWBslRTpt7g+UTBYcB8vU9J4cHfpdXYeLM3tM0tnKksc3Eis0+Q==", "license": "Apache-2.0", "peer": true, "dependencies": { @@ -5566,35 +5378,35 @@ "peerDependencies": { "@angular/core": ">=16.0.0", "@angular/forms": ">=16.0.0", - "@maskito/core": "^3.10.3" + "@maskito/core": "^3.11.1" } }, "node_modules/@maskito/core": { - "version": "3.10.3", - "resolved": "https://registry.npmjs.org/@maskito/core/-/core-3.10.3.tgz", - "integrity": "sha512-4SZeEF6PjDHC+J5ADrJaSrFmgqmGkqfE5Yi6BrNXze9TGvVRy9aHJCizShFvheqCEu6MsK0XprZot28wH9AhjQ==", + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/@maskito/core/-/core-3.11.1.tgz", + "integrity": "sha512-zN5k/BiZXblo8mEFhsGnnXBCqKMkjEGArorOOcpB1/ymZyqF12Dk6IipEsSE6abMnWw4YF2tukzfq73BFZKz8A==", "license": "Apache-2.0", "peer": true }, "node_modules/@maskito/kit": { - "version": "3.10.3", - "resolved": "https://registry.npmjs.org/@maskito/kit/-/kit-3.10.3.tgz", - "integrity": "sha512-4IAL5WPlz4zi6vCMp8KbSAVh67WT+o0PzQ56dU4E7crN1jzBm1cN7MIbGawefOIXwAiqCb8zOSyTv/qqSL0xGQ==", + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/@maskito/kit/-/kit-3.11.1.tgz", + "integrity": "sha512-KOBUqxRz383xJWCoe+Emwxv2oAzUrZobIN+Gntmi5Py2S10XbqYnGX/6W7QHN8CUK2Nx11d3HsxbEQaq5Hinjg==", "license": "Apache-2.0", "peer": true, "peerDependencies": { - "@maskito/core": "^3.10.3" + "@maskito/core": "^3.11.1" } }, "node_modules/@maskito/phone": { - "version": "3.10.3", - "resolved": "https://registry.npmjs.org/@maskito/phone/-/phone-3.10.3.tgz", - "integrity": "sha512-xt0WLrzLbxiS+0j5QoR6lBjU+FvtqfUL3BOEAKcopgUa8lrswZr3g6fRy0BCcvrzpf4Jdpj3FsZcBRd6ljiEkg==", + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/@maskito/phone/-/phone-3.11.1.tgz", + "integrity": "sha512-ptNDPIZQs/v598qydBa9cnvoCE8+k2Sv07kKKVx3vG0V40DQnIlEL+LYKrJJbMIiPOB6CH90hB9eaA9KKReZ6w==", "license": "Apache-2.0", "peer": true, "peerDependencies": { - "@maskito/core": "^3.10.3", - "@maskito/kit": "^3.10.3", + "@maskito/core": "^3.11.1", + "@maskito/kit": "^3.11.1", "libphonenumber-js": ">=1.0.0" } }, @@ -6019,9 +5831,9 @@ } }, "node_modules/@ng-web-apis/common": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@ng-web-apis/common/-/common-4.12.0.tgz", - "integrity": "sha512-OG4ChsEWQ0IbGJ+WrJAiOY5X4jF8f5YUCss961taPeiyhvwtUo4zAuX3UvtV/iJSt8XZ41jaOYFTyMIBGubv4Q==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@ng-web-apis/common/-/common-4.12.2.tgz", + "integrity": "sha512-fjmSpJfu+3i7i/+2U38owTTxoi8EoANQJVaIGmNymyF8EmSrbVCcPP6CXsZ6UsHJwE8IWso7h0cN6kBUqWERfw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.3.0" @@ -6033,9 +5845,9 @@ } }, "node_modules/@ng-web-apis/intersection-observer": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@ng-web-apis/intersection-observer/-/intersection-observer-4.12.0.tgz", - "integrity": "sha512-7MW0y6BrjLKCTUGb5YfsEPYpn17wPmGj8J+2A980ntGNveo9+DILz3KpFHkpS6G6bJGtnD36exU2YvfTUKiyXA==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@ng-web-apis/intersection-observer/-/intersection-observer-4.12.2.tgz", + "integrity": "sha512-hE2jBuRpn/FBcbOZuYwMG/uGW4Y7T+T0g3MiY3eCY+YSZQ5wWtzHdkj8bpdAaAUbHuKJuxtzQG68uMd8yVUMMg==", "license": "Apache-2.0", "peer": true, "dependencies": { @@ -6047,9 +5859,9 @@ } }, "node_modules/@ng-web-apis/mutation-observer": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@ng-web-apis/mutation-observer/-/mutation-observer-4.12.0.tgz", - "integrity": "sha512-Yyz0jpQoGgWzQEhjRH8xC9Umxr2W0hYktuYDNxrmnr6GnBejcfkE+wCon7FhCt6h7BrqR3+Z4cg7TvnyUVHU6Q==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@ng-web-apis/mutation-observer/-/mutation-observer-4.12.2.tgz", + "integrity": "sha512-LEbtahyyBp/LhPgxAsjY3G75bqeWmBTMHYiMH4kHa8/ExH0LSKplB/X9nadUJ9YdMQ8d/DDC9cxQvIozOzcyRA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.3.0" @@ -6060,18 +5872,18 @@ } }, "node_modules/@ng-web-apis/platform": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@ng-web-apis/platform/-/platform-4.12.0.tgz", - "integrity": "sha512-OuwV9OERPvQD+QxS2q84pWg60GlL9O66zl0VBLDR8ARMslBfCg1m70LlbLfQI4mlt4QZzTliUVps1JaGyAEKYA==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@ng-web-apis/platform/-/platform-4.12.2.tgz", + "integrity": "sha512-HO2nm1us87iiOntXwEGv1D5L1kQ4luJlOcWnCPjEwiWE4vxANDis/MnYvJAcwAUQRNikXw8BjgAEo3aWafxDhA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.3.0" } }, "node_modules/@ng-web-apis/resize-observer": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@ng-web-apis/resize-observer/-/resize-observer-4.12.0.tgz", - "integrity": "sha512-ekLcZnqap9OBcoTtOD0/tcOy/STFrxSu3WR0yU9yEM0n7S1mOsKOnXIY4PMAxxWV4LMs91P00wzFHfNNnuOS/g==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@ng-web-apis/resize-observer/-/resize-observer-4.12.2.tgz", + "integrity": "sha512-ogthPEuHRBaJCXv/Df8GCqag52WkKziKx4l/+jp2jmaxKHWtmzW59Ftb7HFfoCzmkb+tVlVdC3EwFyldax2eyw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.3.0" @@ -6082,9 +5894,9 @@ } }, "node_modules/@ng-web-apis/screen-orientation": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@ng-web-apis/screen-orientation/-/screen-orientation-4.12.0.tgz", - "integrity": "sha512-oqZqc9TTpEBNNinVSFjEl/plhoRxh07zMtdG6VMnuY6Lng2l1jfC7vKru2rjEskR+0sYgN8Y8Ttov03i8I9GHg==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@ng-web-apis/screen-orientation/-/screen-orientation-4.12.2.tgz", + "integrity": "sha512-8ZKFrfu0/7coUECmqi+ppk/1lUfHi38N0msmKR+iZvVbDiZcaJhu2SptZEmEkR1pTykp1wbbKSSfdyDb3MK1hQ==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.3.0" @@ -6096,9 +5908,9 @@ } }, "node_modules/@ngtools/webpack": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-19.2.15.tgz", - "integrity": "sha512-H37nop/wWMkSgoU2VvrMzanHePdLRRrX52nC5tT2ZhH3qP25+PrnMyw11PoLDLv3iWXC68uB1AiKNIT+jiQbuQ==", + "version": "19.2.18", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-19.2.18.tgz", + "integrity": "sha512-UHwrNcrq1TfiGbQ04xw6rmsijWqTjsh7gTizrJILMDF4U6xVvSth8FolCyLhAjheT5e9zKfIHXeGxUS0Qgrp9A==", "dev": true, "license": "MIT", "engines": { @@ -6986,6 +6798,20 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.5.tgz", + "integrity": "sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { "version": "4.34.8", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz", @@ -7014,6 +6840,20 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.5.tgz", + "integrity": "sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { "version": "4.34.8", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz", @@ -7028,6 +6868,20 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.5.tgz", + "integrity": "sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-s390x-gnu": { "version": "4.34.8", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz", @@ -7043,9 +6897,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz", - "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz", + "integrity": "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==", "cpu": [ "x64" ], @@ -7069,6 +6923,20 @@ "linux" ] }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.5.tgz", + "integrity": "sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, "node_modules/@rollup/rollup-win32-arm64-msvc": { "version": "4.34.8", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz", @@ -7097,6 +6965,20 @@ "win32" ] }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.5.tgz", + "integrity": "sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@rollup/rollup-win32-x64-msvc": { "version": "4.34.8", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz", @@ -7119,14 +7001,14 @@ "license": "MIT" }, "node_modules/@schematics/angular": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-19.2.15.tgz", - "integrity": "sha512-dz/eoFQKG09POSygpEDdlCehFIMo35HUM2rVV8lx9PfQEibpbGwl1NNQYEbqwVjTyCyD/ILyIXCWPE+EfTnG4g==", + "version": "19.2.18", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-19.2.18.tgz", + "integrity": "sha512-GUR+7RIXm91nq4EZ+Ofg/RccHNyd6S/vPTMd1Q4nCtkgbEgjqFM3F//JVJJDwmwai7+hHJWlsCILz/hHCQOCHQ==", "devOptional": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "19.2.15", - "@angular-devkit/schematics": "19.2.15", + "@angular-devkit/core": "19.2.18", + "@angular-devkit/schematics": "19.2.18", "jsonc-parser": "3.3.1" }, "engines": { @@ -7135,108 +7017,6 @@ "yarn": ">= 1.13.0" } }, - "node_modules/@schematics/angular/node_modules/@angular-devkit/core": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.15.tgz", - "integrity": "sha512-pU2RZYX6vhd7uLSdLwPnuBcr0mXJSjp3EgOXKsrlQFQZevc+Qs+2JdXgIElnOT/aDqtRtriDmLlSbtdE8n3ZbA==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "ajv": "8.17.1", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.2", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^4.0.0" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@schematics/angular/node_modules/@angular-devkit/schematics": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.15.tgz", - "integrity": "sha512-kNOJ+3vekJJCQKWihNmxBkarJzNW09kP5a9E1SRNiQVNOUEeSwcRR0qYotM65nx821gNzjjhJXnAZ8OazWldrg==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "19.2.15", - "jsonc-parser": "3.3.1", - "magic-string": "0.30.17", - "ora": "5.4.1", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@schematics/angular/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@schematics/angular/node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/@schematics/angular/node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "node_modules/@schematics/angular/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "devOptional": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, "node_modules/@sigstore/bundle": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-3.1.0.tgz", @@ -7338,9 +7118,9 @@ "license": "MIT" }, "node_modules/@taiga-ui/cdk": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@taiga-ui/cdk/-/cdk-4.52.0.tgz", - "integrity": "sha512-rYs6xSVWuShQBbLul+7z/SnFeGe+j4qxJwZYb0C6CfAJLHoeIBjEwgY6cT07Eidu91fKaa8EMtETrkXxH5jkPQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@taiga-ui/cdk/-/cdk-4.59.0.tgz", + "integrity": "sha512-7vEDvkrZJRRfev/CzX1kO7XTIasfdfI46yiWaUAYv0eDvX689gFYLAXVepFu1zXHEZjVexgOutk6dLe2gzSmEg==", "license": "Apache-2.0", "dependencies": { "tslib": "2.8.1" @@ -7363,7 +7143,7 @@ "@ng-web-apis/platform": "^4.12.0", "@ng-web-apis/resize-observer": "^4.12.0", "@ng-web-apis/screen-orientation": "^4.12.0", - "@taiga-ui/event-plugins": "^4.6.0", + "@taiga-ui/event-plugins": "^4.7.0", "@taiga-ui/polymorpheus": "^4.9.0", "rxjs": ">=7.0.0" } @@ -7395,9 +7175,9 @@ } }, "node_modules/@taiga-ui/core": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@taiga-ui/core/-/core-4.52.0.tgz", - "integrity": "sha512-MLt2A+SBm4wrp0/SE7zOA70al+ZamoDwZB3OB4e9YmQhsFTULqZxFIWZWZrBaQOtVVOt3mHFOK20rRnCwVYlrg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@taiga-ui/core/-/core-4.59.0.tgz", + "integrity": "sha512-xjkyCpYT5jbFX8wky71/oXIpji0UgQyoOIOwUZDa4yU0YP5EWm59i4zilgMxfARX8QnizbadiH7AN/FE4+hWig==", "license": "Apache-2.0", "dependencies": { "tslib": ">=2.8.1" @@ -7411,9 +7191,9 @@ "@angular/router": ">=16.0.0", "@ng-web-apis/common": "^4.12.0", "@ng-web-apis/mutation-observer": "^4.12.0", - "@taiga-ui/cdk": "^4.52.0", - "@taiga-ui/event-plugins": "^4.6.0", - "@taiga-ui/i18n": "^4.52.0", + "@taiga-ui/cdk": "^4.59.0", + "@taiga-ui/event-plugins": "^4.7.0", + "@taiga-ui/i18n": "^4.59.0", "@taiga-ui/polymorpheus": "^4.9.0", "rxjs": ">=7.0.0" } @@ -7433,9 +7213,9 @@ } }, "node_modules/@taiga-ui/i18n": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@taiga-ui/i18n/-/i18n-4.52.0.tgz", - "integrity": "sha512-sK/ol6H0OR2lBXM6XbSOr02n/ddfKAxNCKiaM88WUn6jxFBYDfEjlQPMvqELXb03wi4kQudo48pnFV4/K6JzxQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@taiga-ui/i18n/-/i18n-4.59.0.tgz", + "integrity": "sha512-IxPzqkORJlSqagvUdmqBL9fuvfRm/Ca/W/bCDEK2GN/4QtSZ0yFzAyQdWduoIJubqyEPMXRbXZGc7WBtDgAMIQ==", "license": "Apache-2.0", "dependencies": { "tslib": ">=2.8.1" @@ -7447,18 +7227,18 @@ } }, "node_modules/@taiga-ui/icons": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@taiga-ui/icons/-/icons-4.52.0.tgz", - "integrity": "sha512-a/mjQ7wjzVGMuK0GosjvO+oH1KzsKLrz+3pLJh+z79iSC3tH+jsaUbI3HNWWgI+0MHHDLSA31yOy1EHLLDRoUw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@taiga-ui/icons/-/icons-4.59.0.tgz", + "integrity": "sha512-zimd9+Q9itsSv/hn4QyZZoBOz6IR7OCBcEMXTwoEtEPFEeyQopo+RcDljMSTCcBAUAXitSdsBqwUcKMxigtH3Q==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.3.0" } }, "node_modules/@taiga-ui/kit": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@taiga-ui/kit/-/kit-4.52.0.tgz", - "integrity": "sha512-ePym6t9KsUfBTfqSwdCf8lUx+sU0hmbLpUdJGNg3KlOTPI6k7zV3bLQjN1hnOU6eoZjaqvFYNMz+D0MbgiZiIQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@taiga-ui/kit/-/kit-4.59.0.tgz", + "integrity": "sha512-Qw8i0Fli6a4y/pOoZPzY3rhvky64H9xrUPvp2BQR/mzFn1roVbP+J125yTiEauf8qHoT1mD6xqI39wj/wDBz1g==", "license": "Apache-2.0", "dependencies": { "tslib": ">=2.8.1" @@ -7468,17 +7248,17 @@ "@angular/core": ">=16.0.0", "@angular/forms": ">=16.0.0", "@angular/router": ">=16.0.0", - "@maskito/angular": "^3.10.3", - "@maskito/core": "^3.10.3", - "@maskito/kit": "^3.10.3", - "@maskito/phone": "^3.10.3", + "@maskito/angular": "^3.11.1", + "@maskito/core": "^3.11.1", + "@maskito/kit": "^3.11.1", + "@maskito/phone": "^3.11.1", "@ng-web-apis/common": "^4.12.0", "@ng-web-apis/intersection-observer": "^4.12.0", "@ng-web-apis/mutation-observer": "^4.12.0", "@ng-web-apis/resize-observer": "^4.12.0", - "@taiga-ui/cdk": "^4.52.0", - "@taiga-ui/core": "^4.52.0", - "@taiga-ui/i18n": "^4.52.0", + "@taiga-ui/cdk": "^4.59.0", + "@taiga-ui/core": "^4.59.0", + "@taiga-ui/i18n": "^4.59.0", "@taiga-ui/polymorpheus": "^4.9.0", "rxjs": ">=7.0.0" } @@ -7497,12 +7277,12 @@ } }, "node_modules/@taiga-ui/styles": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@taiga-ui/styles/-/styles-4.52.0.tgz", - "integrity": "sha512-X0i9Pg9IMpDXvDHm48BmbFpzJq2o1G5KLKNlxvebt/qwxfgallmjVMCD8slvp3Pa5c+QtmrKyDdiIVXR+vO8fw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@taiga-ui/styles/-/styles-4.59.0.tgz", + "integrity": "sha512-rFOKBaZzXqDLMuBl75FYANhN3APylYhTqrU7jUTveIELfLwL+n/C8NzXt+AKHZzJKXacj4UIxAvDIWeE4vnHqA==", "peerDependencies": { - "@taiga-ui/cdk": "^4.52.0", - "@taiga-ui/core": "^4.52.0", + "@taiga-ui/cdk": "^4.59.0", + "@taiga-ui/core": "^4.59.0", "tslib": ">=2.8.1" } }, @@ -7579,9 +7359,9 @@ } }, "node_modules/@tybys/wasm-util": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.0.tgz", - "integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", "dev": true, "license": "MIT", "optional": true, @@ -7684,9 +7464,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.19.6", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", - "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "version": "4.19.7", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.7.tgz", + "integrity": "sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg==", "dev": true, "license": "MIT", "dependencies": { @@ -7714,9 +7494,9 @@ } }, "node_modules/@types/jasmine": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.9.tgz", - "integrity": "sha512-8t4HtkW4wxiPVedMpeZ63n3vlWxEIquo/zc1Tm8ElU+SqVV7+D3Na2PWaJUp179AzTragMWVwkMv7mvty0NfyQ==", + "version": "5.1.12", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.12.tgz", + "integrity": "sha512-1BzPxNsFDLDfj9InVR3IeY0ZVf4o9XV+4mDqoCfyPkbsA7dYyKAPAb2co6wLFlHcvxPlt1wShm7zQdV7uTfLGA==", "dev": true, "license": "MIT" }, @@ -7749,13 +7529,13 @@ "optional": true }, "node_modules/@types/node": { - "version": "24.3.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.1.tgz", - "integrity": "sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g==", + "version": "24.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.1.tgz", + "integrity": "sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~7.10.0" + "undici-types": "~7.16.0" } }, "node_modules/@types/node-forge": { @@ -7790,13 +7570,12 @@ "license": "MIT" }, "node_modules/@types/send": { - "version": "0.17.5", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", - "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.0.tgz", + "integrity": "sha512-zBF6vZJn1IaMpg3xUF25VK3gd3l8zwE0ZLRX7dsQyQi+jp4E8mMDJNGDYnYse+bQhYwWERTxVwHpi3dMOq7RKQ==", "dev": true, "license": "MIT", "dependencies": { - "@types/mime": "^1", "@types/node": "*" } }, @@ -7811,15 +7590,26 @@ } }, "node_modules/@types/serve-static": { - "version": "1.15.8", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", - "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.9.tgz", + "integrity": "sha512-dOTIuqpWLyl3BBXU3maNQsS4A3zuuoYRNIvYSxxhebPfXg2mzWQEPne/nlJ37yOse6uGgR386uTpdsx4D0QZWA==", "dev": true, "license": "MIT", "dependencies": { "@types/http-errors": "*", "@types/node": "*", - "@types/send": "*" + "@types/send": "<1" + } + }, + "node_modules/@types/serve-static/node_modules/@types/send": { + "version": "0.17.5", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", + "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" } }, "node_modules/@types/sockjs": { @@ -8191,14 +7981,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.42.0.tgz", - "integrity": "sha512-vfVpLHAhbPjilrabtOSNcUDmBboQNrJUiNAGoImkZKnMjs2TIcWG33s4Ds0wY3/50aZmTMqJa6PiwkwezaAklg==", + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.2.tgz", + "integrity": "sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.42.0", - "@typescript-eslint/types": "^8.42.0", + "@typescript-eslint/tsconfig-utils": "^8.46.2", + "@typescript-eslint/types": "^8.46.2", "debug": "^4.3.4" }, "engines": { @@ -8213,14 +8003,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.42.0.tgz", - "integrity": "sha512-51+x9o78NBAVgQzOPd17DkNTnIzJ8T/O2dmMBLoK9qbY0Gm52XJcdJcCl18ExBMiHo6jPMErUQWUv5RLE51zJw==", + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.2.tgz", + "integrity": "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.42.0", - "@typescript-eslint/visitor-keys": "8.42.0" + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/visitor-keys": "8.46.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -8231,9 +8021,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.42.0.tgz", - "integrity": "sha512-kHeFUOdwAJfUmYKjR3CLgZSglGHjbNTi1H8sTYRYV2xX6eNz4RyJ2LIgsDLKf8Yi0/GL1WZAC/DgZBeBft8QAQ==", + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.2.tgz", + "integrity": "sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==", "dev": true, "license": "MIT", "engines": { @@ -8427,9 +8217,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.42.0.tgz", - "integrity": "sha512-LdtAWMiFmbRLNP7JNeY0SqEtJvGMYSzfiWBSmx+VSZ1CH+1zyl8Mmw1TT39OrtsRvIYShjJWzTDMPWZJCpwBlw==", + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.2.tgz", + "integrity": "sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==", "dev": true, "license": "MIT", "engines": { @@ -8441,16 +8231,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.42.0.tgz", - "integrity": "sha512-ku/uYtT4QXY8sl9EDJETD27o3Ewdi72hcXg1ah/kkUgBvAYHLwj2ofswFFNXS+FL5G+AGkxBtvGt8pFBHKlHsQ==", + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.2.tgz", + "integrity": "sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.42.0", - "@typescript-eslint/tsconfig-utils": "8.42.0", - "@typescript-eslint/types": "8.42.0", - "@typescript-eslint/visitor-keys": "8.42.0", + "@typescript-eslint/project-service": "8.46.2", + "@typescript-eslint/tsconfig-utils": "8.46.2", + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/visitor-keys": "8.46.2", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -8470,16 +8260,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.42.0.tgz", - "integrity": "sha512-JnIzu7H3RH5BrKC4NoZqRfmjqCIS1u3hGZltDYJgkVdqAezl4L9d1ZLw+36huCujtSBSAirGINF/S4UxOcR+/g==", + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.2.tgz", + "integrity": "sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.42.0", - "@typescript-eslint/types": "8.42.0", - "@typescript-eslint/typescript-estree": "8.42.0" + "@typescript-eslint/scope-manager": "8.46.2", + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/typescript-estree": "8.46.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -8494,13 +8284,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.42.0.tgz", - "integrity": "sha512-3WbiuzoEowaEn8RSnhJBrxSwX8ULYE9CXaPepS2C2W3NSA5NNIvBaslpBSBElPq0UGr0xVJlXFWOAKIkyylydQ==", + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.2.tgz", + "integrity": "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.42.0", + "@typescript-eslint/types": "8.46.2", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -9086,16 +8876,16 @@ } }, "node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "devOptional": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -9103,9 +8893,9 @@ } }, "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -9133,27 +8923,6 @@ "ajv": "^8.8.2" } }, - "node_modules/angular-cli-ghpages": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/angular-cli-ghpages/-/angular-cli-ghpages-1.0.7.tgz", - "integrity": "sha512-7uq+NSqmhVBnA1uimVQVoQfXP80aSJc/nZGdRUiADcTeRQFPamaQUbh4bn2EHiC9TJn44lDOEGnzdhAej0wz6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "commander": "^3.0.0-0", - "fs-extra": "^9.0.1", - "gh-pages": "^3.1.0" - }, - "bin": { - "angular-cli-ghpages": "angular-cli-ghpages", - "ngh": "angular-cli-ghpages" - }, - "peerDependencies": { - "@angular-devkit/architect": ">= 0.900 < 0.1602.0", - "@angular-devkit/core": "^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0", - "@angular-devkit/schematics": "^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" - } - }, "node_modules/angular-eslint": { "version": "20.1.1", "resolved": "https://registry.npmjs.org/angular-eslint/-/angular-eslint-20.1.1.tgz", @@ -9178,9 +8947,9 @@ } }, "node_modules/angular-eslint/node_modules/@angular-devkit/core": { - "version": "20.2.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.2.2.tgz", - "integrity": "sha512-SC+f5isSWJBpEgR+R7jP++2Z14WExNWLAdKpIickLWjuL8FlGkj+kaF3dWXhh0KcXo+r6kKb4pWUptSaqer5gA==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.7.tgz", + "integrity": "sha512-psmcjwYcXve4sLrcdnARc15/Wfd3RpydbtLo9+mViNzk5HQ6L2eEztKl/2QVYMgzZVIa1GfhjwUllVCyLAv3sg==", "dev": true, "license": "MIT", "dependencies": { @@ -9206,13 +8975,13 @@ } }, "node_modules/angular-eslint/node_modules/@angular-devkit/schematics": { - "version": "20.2.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-20.2.2.tgz", - "integrity": "sha512-rtL7slZjzdChQoiADKZv/Ra8D3C3tIw/WcVxd2stiLHdK/Oaf9ejx5m/X9o0QMEbNsy2Fy/RKodNqmz1CjzpCg==", + "version": "20.3.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-20.3.7.tgz", + "integrity": "sha512-DUxcQBPKO69p56ZgIdVfxWyLiSjdcUoD6BH9/nWHp0QiqRAR6GcXP4SFax76JPl2WsiCp4hHZ233Hf69AP1xew==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "20.2.2", + "@angular-devkit/core": "20.3.7", "jsonc-parser": "3.3.1", "magic-string": "0.30.17", "ora": "8.2.0", @@ -9298,45 +9067,10 @@ "typescript": "*" } }, - "node_modules/angular-eslint/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/angular-eslint/node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, "node_modules/angular-eslint/node_modules/chalk": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.0.tgz", - "integrity": "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "dev": true, "license": "MIT", "engines": { @@ -9402,16 +9136,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/angular-eslint/node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, "node_modules/angular-eslint/node_modules/ora": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", @@ -9470,16 +9194,16 @@ } }, "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.1.1.tgz", + "integrity": "sha512-Zhl0ErHcSRUaVfGUeUdDuLgpkEo8KIFjB4Y9uAc46ScOpdDiU1Dbyplh7qWJeJ/ZHpbyMSM26+X3BySgnIz40Q==", "dev": true, "license": "MIT", "dependencies": { - "type-fest": "^0.21.3" + "environment": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -9499,9 +9223,9 @@ } }, "node_modules/ansi-regex": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz", - "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", "engines": { @@ -9638,16 +9362,6 @@ "node": ">=8" } }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array.prototype.findlastindex": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", @@ -9750,16 +9464,6 @@ "node": ">=8" } }, - "node_modules/async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash": "^4.17.14" - } - }, "node_modules/async-function": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", @@ -9770,16 +9474,6 @@ "node": ">= 0.4" } }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/autoprefixer": { "version": "10.4.20", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", @@ -9952,6 +9646,16 @@ "node": "^4.5.0 || >= 5.9" } }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.20", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.20.tgz", + "integrity": "sha512-JMWsdF+O8Orq3EMukbUN1QfbLK9mX2CkUmQBcW2T0s8OmdAUL5LLM/6wFwSrqXzlXB13yhyK9gTKS1rIizOduQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, "node_modules/batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", @@ -10111,9 +9815,9 @@ } }, "node_modules/browserslist": { - "version": "4.25.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.4.tgz", - "integrity": "sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg==", + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz", + "integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==", "dev": true, "funding": [ { @@ -10131,10 +9835,11 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001737", - "electron-to-chromium": "^1.5.211", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.3" + "baseline-browser-mapping": "^2.8.19", + "caniuse-lite": "^1.0.30001751", + "electron-to-chromium": "^1.5.238", + "node-releases": "^2.0.26", + "update-browserslist-db": "^1.1.4" }, "bin": { "browserslist": "cli.js" @@ -10277,34 +9982,17 @@ "dev": true, "license": "ISC" }, - "node_modules/cacache/node_modules/mkdirp": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/cacache/node_modules/tar": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", - "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.1.tgz", + "integrity": "sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g==", "dev": true, "license": "ISC", "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", - "minizlib": "^3.0.1", - "mkdirp": "^3.0.1", + "minizlib": "^3.1.0", "yallist": "^5.0.0" }, "engines": { @@ -10322,24 +10010,28 @@ } }, "node_modules/cacheable": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.10.4.tgz", - "integrity": "sha512-Gd7ccIUkZ9TE2odLQVS+PDjIvQCdJKUlLdJRVvZu0aipj07Qfx+XIej7hhDrKGGoIxV5m5fT/kOJNJPQhQneRg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.1.1.tgz", + "integrity": "sha512-LmF4AXiSNdiRbI2UjH8pAp9NIXxeQsTotpEaegPiDcnN0YPygDJDV3l/Urc0mL72JWdATEorKqIHEx55nDlONg==", "dev": true, "license": "MIT", "dependencies": { - "hookified": "^1.11.0", - "keyv": "^5.5.0" + "@cacheable/memoize": "^2.0.3", + "@cacheable/memory": "^2.0.3", + "@cacheable/utils": "^2.1.0", + "hookified": "^1.12.2", + "keyv": "^5.5.3", + "qified": "^0.5.0" } }, "node_modules/cacheable/node_modules/keyv": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.0.tgz", - "integrity": "sha512-QG7qR2tijh1ftOvClut4YKKg1iW6cx3GZsKoGyJPxHkGWK9oJhG9P3j5deP0QQOGDowBMVQFaP+Vm4NpGYvmIQ==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.3.tgz", + "integrity": "sha512-h0Un1ieD+HUrzBH6dJXhod3ifSghk5Hw/2Y4/KHBziPlZecrFyE9YOTPU6eOs0V9pYl8gOs86fkr/KN8lUX39A==", "dev": true, "license": "MIT", "dependencies": { - "@keyv/serialize": "^1.1.0" + "@keyv/serialize": "^1.1.1" } }, "node_modules/call-bind": { @@ -10403,9 +10095,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001739", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001739.tgz", - "integrity": "sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA==", + "version": "1.0.30001751", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz", + "integrity": "sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==", "dev": true, "funding": [ { @@ -10445,44 +10137,22 @@ "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.0.tgz", "integrity": "sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==", "dev": true, - "license": "MIT" - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "MIT" + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "is-glob": "^4.0.1" + "readdirp": "^4.0.1" }, "engines": { - "node": ">= 6" + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/chownr": { @@ -10754,11 +10424,14 @@ "license": "MIT" }, "node_modules/commander": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.1.tgz", + "integrity": "sha512-2JkV3gUZUVrbNA+1sjBOYLsMZ5cEEl8GTFP2a4AVz5hvasAMCQ1D2l2le/cX+pV4N6ZU17zjUahLpIXRrnWL8A==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=20" + } }, "node_modules/common-path-prefix": { "version": "3.0.0", @@ -10767,13 +10440,6 @@ "dev": true, "license": "ISC" }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true, - "license": "MIT" - }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -10969,13 +10635,13 @@ } }, "node_modules/core-js-compat": { - "version": "3.45.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.45.1.tgz", - "integrity": "sha512-tqTt5T4PzsMIZ430XGviK4vzYSoeNJ6CXODi6c/voxOT6IZqBht5/EKaSNnYiEjjRYxjVz7DQIsOsY0XNi8PIA==", + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.46.0.tgz", + "integrity": "sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law==", "dev": true, "license": "MIT", "dependencies": { - "browserslist": "^4.25.3" + "browserslist": "^4.26.3" }, "funding": { "type": "opencollective", @@ -11220,9 +10886,9 @@ } }, "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", "dependencies": { @@ -11359,9 +11025,9 @@ } }, "node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -11533,23 +11199,16 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.214", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.214.tgz", - "integrity": "sha512-TpvUNdha+X3ybfU78NoQatKvQEm1oq3lf2QbnmCEdw+Bd9RuIAY+hJTvq1avzHM0f7EJfnH3vbCnbzKzisc/9Q==", + "version": "1.5.239", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.239.tgz", + "integrity": "sha512-1y5w0Zsq39MSPmEjHjbizvhYoTaulVtivpxkp5q5kaPmQtsK6/2nvAzGRxNMS9DoYySp9PkW0MAQDwU1m764mg==", "dev": true, "license": "ISC" }, - "node_modules/email-addresses": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz", - "integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==", - "dev": true, - "license": "MIT" - }, "node_modules/emoji-regex": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.5.0.tgz", - "integrity": "sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg==", + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "dev": true, "license": "MIT" }, @@ -11584,6 +11243,20 @@ "iconv-lite": "^0.6.2" } }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/engine.io": { "version": "6.6.4", "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz", @@ -11721,9 +11394,9 @@ } }, "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -11989,26 +11662,25 @@ } }, "node_modules/eslint": { - "version": "9.34.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.34.0.tgz", - "integrity": "sha512-RNCHRX5EwdrESy3Jc9o8ie8Bog+PeYvvSR8sDGoZxNFTvZ4dlxUB3WzQ3bQMztFrSRODGrLLj8g6OFuGY/aiQg==", + "version": "9.38.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.38.0.tgz", + "integrity": "sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.0", - "@eslint/config-helpers": "^0.3.1", - "@eslint/core": "^0.15.2", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.1", + "@eslint/core": "^0.16.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.34.0", - "@eslint/plugin-kit": "^0.3.5", + "@eslint/js": "9.38.0", + "@eslint/plugin-kit": "^0.4.0", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", @@ -12124,9 +11796,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", - "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", "dev": true, "license": "MIT", "dependencies": { @@ -12152,15 +11824,15 @@ } }, "node_modules/eslint-plugin-boundaries": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-boundaries/-/eslint-plugin-boundaries-5.0.1.tgz", - "integrity": "sha512-QBw1TgoA3JnD+AQ8EHqZL8LtiFVREnFmD2BnHzVl38UKtRTds8rawIg03ZLwFs/90yKSh+DVVXRpvVK631Z/0w==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-boundaries/-/eslint-plugin-boundaries-5.1.0.tgz", + "integrity": "sha512-tgmq22Z+hEb40D8SDr+QavrioSuMvpymA5AT0t0JoDc4lJ6+AQ1S5EzoRo5kfqoA5YEcTKlTTd0a4gYrWSNj0Q==", "dev": true, "license": "MIT", "dependencies": { "chalk": "4.1.2", "eslint-import-resolver-node": "0.3.9", - "eslint-module-utils": "2.12.0", + "eslint-module-utils": "2.12.1", "micromatch": "4.0.8" }, "engines": { @@ -12225,24 +11897,6 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-plugin-import/node_modules/eslint-module-utils": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", - "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, "node_modules/eslint-plugin-import/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -12512,9 +12166,9 @@ } }, "node_modules/exponential-backoff": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz", - "integrity": "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", + "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", "dev": true, "license": "Apache-2.0" }, @@ -12780,34 +12434,6 @@ "node": ">=16.0.0" } }, - "node_modules/filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/filenamify": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", - "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.1", - "trim-repeated": "^1.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -13026,19 +12652,18 @@ } }, "node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, "license": "MIT", "dependencies": { - "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": ">=10" + "node": ">=6 <7 || >=8" } }, "node_modules/fs-minipass": { @@ -13117,6 +12742,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -13138,9 +12773,9 @@ } }, "node_modules/get-east-asian-width": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.1.tgz", - "integrity": "sha512-R1QfovbPsKmosqTnPoRFiJ7CF9MLRgb53ChvMZm+r4p76/+8yKDy17qLL2PKInORy2RkZZekuK0efYgmzTkXyQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", "dev": true, "license": "MIT", "engines": { @@ -13178,254 +12813,46 @@ "node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/get-symbol-description": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", - "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-tsconfig": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", - "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, - "node_modules/gh-pages": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-3.2.3.tgz", - "integrity": "sha512-jA1PbapQ1jqzacECfjUaO9gV8uBgU6XNMV0oXLtfCX3haGLe5Atq8BxlrADhbD6/UdG9j6tZLWAkAybndOXTJg==", - "dev": true, - "license": "MIT", - "dependencies": { - "async": "^2.6.1", - "commander": "^2.18.0", - "email-addresses": "^3.0.1", - "filenamify": "^4.3.0", - "find-cache-dir": "^3.3.1", - "fs-extra": "^8.1.0", - "globby": "^6.1.0" - }, - "bin": { - "gh-pages": "bin/gh-pages.js", - "gh-pages-clean": "bin/gh-pages-clean.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/gh-pages/node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gh-pages/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/gh-pages/node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, - "license": "MIT", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/gh-pages/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/gh-pages/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/gh-pages/node_modules/globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gh-pages/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/gh-pages/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/gh-pages/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gh-pages/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gh-pages/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "dev": true, "license": "MIT", "dependencies": { - "p-limit": "^2.2.0" + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/gh-pages/node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "dev": true, "license": "MIT", "dependencies": { - "find-up": "^4.0.0" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" }, "engines": { - "node": ">=8" - } - }, - "node_modules/gh-pages/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gh-pages/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "node_modules/get-tsconfig": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", "dev": true, "license": "MIT", - "engines": { - "node": ">= 4.0.0" + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, "node_modules/glob": { @@ -13464,9 +12891,9 @@ } }, "node_modules/glob-to-regex.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/glob-to-regex.js/-/glob-to-regex.js-1.0.1.tgz", - "integrity": "sha512-CG/iEvgQqfzoVsMUbxSJcwbG2JwyZ3naEqPkeltwl0BSS8Bp83k3xlGms+0QdWFUAwV+uvo80wNswKF6FWEkKg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/glob-to-regex.js/-/glob-to-regex.js-1.2.0.tgz", + "integrity": "sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -13747,9 +13174,9 @@ } }, "node_modules/hookified": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.12.0.tgz", - "integrity": "sha512-hMr1Y9TCLshScrBbV2QxJ9BROddxZ12MX9KsCtuGGy/3SmmN5H1PllKerrVlSotur9dlE8hmUKAOSa3WDzsZmQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.12.2.tgz", + "integrity": "sha512-aokUX1VdTpI0DUsndvW+OiwmBpKCu/NgRsSSkuSY0zq8PY6Q6a+lmOfAFDXAAOtBqJELvcWY9L1EVtzjbQcMdg==", "dev": true, "license": "MIT" }, @@ -14015,9 +13442,9 @@ } }, "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", + "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", "dev": true, "license": "MIT", "dependencies": { @@ -14025,6 +13452,10 @@ }, "engines": { "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/icss-utils": { @@ -14099,9 +13530,9 @@ } }, "node_modules/immutable": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz", - "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz", + "integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==", "dev": true, "license": "MIT" }, @@ -14427,14 +13858,15 @@ } }, "node_modules/is-generator-function": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", - "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "get-proto": "^1.0.0", + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" }, @@ -14514,9 +13946,9 @@ } }, "node_modules/is-network-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", - "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.0.tgz", + "integrity": "sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==", "dev": true, "license": "MIT", "engines": { @@ -15026,14 +14458,11 @@ "license": "MIT" }, "node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -15254,6 +14683,31 @@ "concat-map": "0.0.1" } }, + "node_modules/karma/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/karma/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -15273,6 +14727,19 @@ "dev": true, "license": "MIT" }, + "node_modules/karma/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/karma/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -15296,6 +14763,32 @@ "node": "*" } }, + "node_modules/karma/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/karma/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/karma/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -15503,17 +14996,6 @@ "node": ">=4" } }, - "node_modules/less/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=6" - } - }, "node_modules/less/node_modules/semver": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", @@ -15552,9 +15034,9 @@ } }, "node_modules/libphonenumber-js": { - "version": "1.12.15", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.15.tgz", - "integrity": "sha512-TMDCtIhWUDHh91wRC+wFuGlIzKdPzaTUHHVrIZ3vPUEoNaXFLrsIQ1ZpAeZeXApIF6rvDksMTvjrIQlLKaYxqQ==", + "version": "1.12.24", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.24.tgz", + "integrity": "sha512-l5IlyL9AONj4voSd7q9xkuQOL4u8Ty44puTic7J88CmdXkxfGsRfoVLXHCxppwehgpb/Chdb80FFehHqjN3ItQ==", "license": "MIT", "peer": true }, @@ -15576,19 +15058,6 @@ } } }, - "node_modules/lilconfig": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", - "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -15597,19 +15066,16 @@ "license": "MIT" }, "node_modules/lint-staged": { - "version": "16.1.6", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.1.6.tgz", - "integrity": "sha512-U4kuulU3CKIytlkLlaHcGgKscNfJPNTiDF2avIUGFCv7K95/DCYQ7Ra62ydeRWmgQGg9zJYw2dzdbztwJlqrow==", + "version": "16.2.6", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.2.6.tgz", + "integrity": "sha512-s1gphtDbV4bmW1eylXpVMk2u7is7YsrLl8hzrtvC70h4ByhcMLZFY01Fx05ZUDNuv1H8HO4E+e2zgejV1jVwNw==", "dev": true, "license": "MIT", "dependencies": { - "chalk": "^5.6.0", - "commander": "^14.0.0", - "debug": "^4.4.1", - "lilconfig": "^3.1.3", - "listr2": "^9.0.3", + "commander": "^14.0.1", + "listr2": "^9.0.5", "micromatch": "^4.0.8", - "nano-spawn": "^1.0.2", + "nano-spawn": "^2.0.0", "pidtree": "^0.6.0", "string-argv": "^0.3.2", "yaml": "^2.8.1" @@ -15625,9 +15091,9 @@ } }, "node_modules/lint-staged/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, "license": "MIT", "engines": { @@ -15637,27 +15103,38 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/lint-staged/node_modules/chalk": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.0.tgz", - "integrity": "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ==", + "node_modules/lint-staged/node_modules/cli-truncate": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.1.1.tgz", + "integrity": "sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==", "dev": true, "license": "MIT", + "dependencies": { + "slice-ansi": "^7.1.0", + "string-width": "^8.0.0" + }, "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" + "node": ">=20" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lint-staged/node_modules/commander": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.0.tgz", - "integrity": "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==", + "node_modules/lint-staged/node_modules/cli-truncate/node_modules/string-width": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", + "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", "dev": true, "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.0", + "strip-ansi": "^7.1.0" + }, "engines": { "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lint-staged/node_modules/eventemitter3": { @@ -15667,14 +15144,30 @@ "dev": true, "license": "MIT" }, + "node_modules/lint-staged/node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lint-staged/node_modules/listr2": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.3.tgz", - "integrity": "sha512-0aeh5HHHgmq1KRdMMDHfhMWQmIT/m7nRDTlxlFqni2Sp0had9baqsjJRvDGdlvgd6NmPE0nPloOipiQJGFtTHQ==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz", + "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==", "dev": true, "license": "MIT", "dependencies": { - "cli-truncate": "^4.0.0", + "cli-truncate": "^5.0.0", "colorette": "^2.0.20", "eventemitter3": "^5.0.1", "log-update": "^6.1.0", @@ -15685,10 +15178,27 @@ "node": ">=20.0.0" } }, + "node_modules/lint-staged/node_modules/slice-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, "node_modules/lint-staged/node_modules/wrap-ansi": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", - "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "dev": true, "license": "MIT", "dependencies": { @@ -15722,9 +15232,9 @@ } }, "node_modules/listr2/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, "license": "MIT", "engines": { @@ -15742,9 +15252,9 @@ "license": "MIT" }, "node_modules/listr2/node_modules/wrap-ansi": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", - "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "dev": true, "license": "MIT", "dependencies": { @@ -15787,13 +15297,17 @@ } }, "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", "dev": true, "license": "MIT", "engines": { "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/loader-utils": { @@ -15979,26 +15493,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-update/node_modules/ansi-escapes": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", - "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", - "dev": true, - "license": "MIT", - "dependencies": { - "environment": "^1.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/log-update/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, "license": "MIT", "engines": { @@ -16025,9 +15523,9 @@ } }, "node_modules/log-update/node_modules/slice-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", - "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", "dev": true, "license": "MIT", "dependencies": { @@ -16042,9 +15540,9 @@ } }, "node_modules/log-update/node_modules/wrap-ansi": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", - "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "dev": true, "license": "MIT", "dependencies": { @@ -16087,16 +15585,13 @@ } }, "node_modules/magic-string": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz", - "integrity": "sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==", + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", "devOptional": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/make-dir": { @@ -16177,9 +15672,9 @@ } }, "node_modules/memfs": { - "version": "4.38.2", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.38.2.tgz", - "integrity": "sha512-FpWsVHpAkoSh/LfY1BgAl72BVd374ooMRtDi2VqzBycX4XEfvC0XKACCe0C9VRZoYq5viuoyTv6lYXZ/Q7TrLQ==", + "version": "4.49.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.49.0.tgz", + "integrity": "sha512-L9uC9vGuc4xFybbdOpRLoOAOq1YEBBsocCs5NVW32DfU+CZWWIn3OVF+lB8Gp4ttBVSMazwrTrjv8ussX/e3VQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -16190,9 +15685,6 @@ "tree-dump": "^1.0.3", "tslib": "^2.0.0" }, - "engines": { - "node": ">= 4.0.0" - }, "funding": { "type": "github", "url": "https://github.com/sponsors/streamich" @@ -16529,9 +16021,9 @@ "license": "ISC" }, "node_modules/minizlib": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", - "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", "dev": true, "license": "MIT", "dependencies": { @@ -16674,9 +16166,9 @@ } }, "node_modules/nano-spawn": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nano-spawn/-/nano-spawn-1.0.2.tgz", - "integrity": "sha512-21t+ozMQDAL/UGgQVBbZ/xXvNO10++ZPuTmKRO8k9V3AClVRht49ahtDjfY8l1q6nSHOrE5ASfthzH3ol6R/hg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nano-spawn/-/nano-spawn-2.0.0.tgz", + "integrity": "sha512-tacvGzUY5o2D8CBh2rrwxyNojUsZNU2zjNTzKQrkgGJQTbGAfArVWXSKMBokBeeg6C7OLRGUEyoFlYbfeWQIqw==", "dev": true, "license": "MIT", "engines": { @@ -16706,9 +16198,9 @@ } }, "node_modules/napi-postinstall": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.3.tgz", - "integrity": "sha512-uTp172LLXSxuSYHv/kou+f6KW3SMppU9ivthaVTXian9sOt3XM/zHYHpRZiLgQoxeWfYUnslNWQHF1+G71xcow==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", "dev": true, "license": "MIT", "bin": { @@ -16746,6 +16238,20 @@ "node": ">= 4.4.x" } }, + "node_modules/needle/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/negotiator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", @@ -16816,9 +16322,9 @@ } }, "node_modules/node-gyp": { - "version": "11.4.2", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-11.4.2.tgz", - "integrity": "sha512-3gD+6zsrLQH7DyYOUIutaauuXrcyxeTPyQuZQCQoNPZMHMMS5m4y0xclNpvYzoK3VNzuyxT6eF4mkIL4WSZ1eQ==", + "version": "11.5.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-11.5.0.tgz", + "integrity": "sha512-ra7Kvlhxn5V9Slyus0ygMa2h+UqExPqUIkfk7Pc8QTLT956JLSy51uWFwHtIYy0vI8cB4BDhc/S03+880My/LQ==", "dev": true, "license": "MIT", "dependencies": { @@ -16870,40 +16376,23 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16" - } - }, - "node_modules/node-gyp/node_modules/mkdirp": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, + "dev": true, + "license": "ISC", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=16" } }, "node_modules/node-gyp/node_modules/tar": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", - "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.1.tgz", + "integrity": "sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g==", "dev": true, "license": "ISC", "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", - "minizlib": "^3.0.1", - "mkdirp": "^3.0.1", + "minizlib": "^3.1.0", "yallist": "^5.0.0" }, "engines": { @@ -16937,9 +16426,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "version": "2.0.26", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.26.tgz", + "integrity": "sha512-S2M9YimhSjBSvYnlr5/+umAnPHE++ODwt5e2Ij6FoX45HA/s4vHdkDx1eax2pAPeAOqu4s9b7ppahsyEFdVqQA==", "dev": true, "license": "MIT" }, @@ -17492,16 +16981,6 @@ "node": ">= 4" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -17665,6 +17144,7 @@ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8" } @@ -17774,36 +17254,14 @@ } }, "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true, "license": "MIT", - "dependencies": { - "pinkie": "^2.0.0" - }, + "optional": true, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, "node_modules/piscina": { @@ -18263,6 +17721,19 @@ "dev": true, "license": "MIT" }, + "node_modules/qified": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/qified/-/qified-0.5.1.tgz", + "integrity": "sha512-+BtFN3dCP+IaFA6IYNOu/f/uK1B8xD2QWyOeCse0rjtAebBmkzgd2d1OAXi3ikAzJMIBSdzZDNZ3wZKEUDQs5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hookified": "^1.12.2" + }, + "engines": { + "node": ">=20" + } + }, "node_modules/qjobs": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", @@ -18375,29 +17846,17 @@ } }, "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, "license": "MIT", "engines": { - "node": ">=8.6" + "node": ">= 14.18.0" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, "node_modules/reflect-metadata": { @@ -18438,9 +17897,9 @@ "license": "MIT" }, "node_modules/regenerate-unicode-properties": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", - "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", "dev": true, "license": "MIT", "dependencies": { @@ -18486,18 +17945,18 @@ } }, "node_modules/regexpu-core": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", - "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", + "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", "dev": true, "license": "MIT", "dependencies": { "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.2.0", + "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", - "regjsparser": "^0.12.0", + "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" + "unicode-match-property-value-ecmascript": "^2.2.1" }, "engines": { "node": ">=4" @@ -18511,31 +17970,18 @@ "license": "MIT" }, "node_modules/regjsparser": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", - "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", + "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "jsesc": "~3.0.2" + "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -18747,6 +18193,20 @@ "fsevents": "~2.3.2" } }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz", + "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/rollup/node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", @@ -18755,9 +18215,9 @@ "license": "MIT" }, "node_modules/run-applescript": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", - "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", "dev": true, "license": "MIT", "engines": { @@ -18945,36 +18405,6 @@ } } }, - "node_modules/sass/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/sass/node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/sax": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", @@ -18984,9 +18414,9 @@ "optional": true }, "node_modules/schema-utils": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", - "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "dev": true, "license": "MIT", "dependencies": { @@ -19003,6 +18433,24 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/schema-utils/node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -19284,15 +18732,15 @@ } }, "node_modules/sharp": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.3.tgz", - "integrity": "sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg==", + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.4.tgz", + "integrity": "sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "color": "^4.2.3", - "detect-libc": "^2.0.4", + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.0", "semver": "^7.7.2" }, "engines": { @@ -19302,28 +18750,28 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.34.3", - "@img/sharp-darwin-x64": "0.34.3", - "@img/sharp-libvips-darwin-arm64": "1.2.0", - "@img/sharp-libvips-darwin-x64": "1.2.0", - "@img/sharp-libvips-linux-arm": "1.2.0", - "@img/sharp-libvips-linux-arm64": "1.2.0", - "@img/sharp-libvips-linux-ppc64": "1.2.0", - "@img/sharp-libvips-linux-s390x": "1.2.0", - "@img/sharp-libvips-linux-x64": "1.2.0", - "@img/sharp-libvips-linuxmusl-arm64": "1.2.0", - "@img/sharp-libvips-linuxmusl-x64": "1.2.0", - "@img/sharp-linux-arm": "0.34.3", - "@img/sharp-linux-arm64": "0.34.3", - "@img/sharp-linux-ppc64": "0.34.3", - "@img/sharp-linux-s390x": "0.34.3", - "@img/sharp-linux-x64": "0.34.3", - "@img/sharp-linuxmusl-arm64": "0.34.3", - "@img/sharp-linuxmusl-x64": "0.34.3", - "@img/sharp-wasm32": "0.34.3", - "@img/sharp-win32-arm64": "0.34.3", - "@img/sharp-win32-ia32": "0.34.3", - "@img/sharp-win32-x64": "0.34.3" + "@img/sharp-darwin-arm64": "0.34.4", + "@img/sharp-darwin-x64": "0.34.4", + "@img/sharp-libvips-darwin-arm64": "1.2.3", + "@img/sharp-libvips-darwin-x64": "1.2.3", + "@img/sharp-libvips-linux-arm": "1.2.3", + "@img/sharp-libvips-linux-arm64": "1.2.3", + "@img/sharp-libvips-linux-ppc64": "1.2.3", + "@img/sharp-libvips-linux-s390x": "1.2.3", + "@img/sharp-libvips-linux-x64": "1.2.3", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.3", + "@img/sharp-libvips-linuxmusl-x64": "1.2.3", + "@img/sharp-linux-arm": "0.34.4", + "@img/sharp-linux-arm64": "0.34.4", + "@img/sharp-linux-ppc64": "0.34.4", + "@img/sharp-linux-s390x": "0.34.4", + "@img/sharp-linux-x64": "0.34.4", + "@img/sharp-linuxmusl-arm64": "0.34.4", + "@img/sharp-linuxmusl-x64": "0.34.4", + "@img/sharp-wasm32": "0.34.4", + "@img/sharp-win32-arm64": "0.34.4", + "@img/sharp-win32-ia32": "0.34.4", + "@img/sharp-win32-x64": "0.34.4" } }, "node_modules/sharp-cli": { @@ -19805,9 +19253,9 @@ } }, "node_modules/sharp-cli/node_modules/lru-cache": { - "version": "11.2.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.1.tgz", - "integrity": "sha512-r8LA6i4LP4EeWOhqBaZZjDWwehd1xUJPCJd9Sv300H0ZmcUER4+JPh7bqqZeqs1o5pgtgvXm+d9UGrB5zZGDiQ==", + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.2.tgz", + "integrity": "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==", "dev": true, "license": "ISC", "engines": { @@ -19848,9 +19296,9 @@ } }, "node_modules/sharp-cli/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, "license": "ISC", "bin": { @@ -19903,9 +19351,9 @@ } }, "node_modules/sharp/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, "license": "ISC", "bin": { @@ -20106,9 +19554,9 @@ } }, "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, "license": "MIT", "engines": { @@ -20317,6 +19765,19 @@ "webpack": "^5.72.1" } }, + "node_modules/source-map-loader/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -20478,41 +19939,6 @@ "node": ">=8.0" } }, - "node_modules/streamroller/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/streamroller/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/streamroller/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -20667,9 +20093,9 @@ } }, "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, "license": "MIT", "dependencies": { @@ -20729,33 +20155,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-outer/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/stylelint": { - "version": "16.23.1", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.23.1.tgz", - "integrity": "sha512-dNvDTsKV1U2YtiUDfe9d2gp902veFeo3ecCWdGlmLm2WFrAV0+L5LoOj/qHSBABQwMsZPJwfC4bf39mQm1S5zw==", + "version": "16.25.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.25.0.tgz", + "integrity": "sha512-Li0avYWV4nfv1zPbdnxLYBGq4z8DVZxbRgx4Kn6V+Uftz1rMoF1qiEI3oL4kgWqyYgCgs7gT5maHNZ82Gk03vQ==", "dev": true, "funding": [ { @@ -20773,16 +20176,16 @@ "@csstools/css-tokenizer": "^3.0.4", "@csstools/media-query-list-parser": "^4.0.3", "@csstools/selector-specificity": "^5.0.0", - "@dual-bundle/import-meta-resolve": "^4.1.0", + "@dual-bundle/import-meta-resolve": "^4.2.1", "balanced-match": "^2.0.0", "colord": "^2.9.3", "cosmiconfig": "^9.0.0", "css-functions-list": "^3.2.3", "css-tree": "^3.1.0", - "debug": "^4.4.1", + "debug": "^4.4.3", "fast-glob": "^3.3.3", "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^10.1.3", + "file-entry-cache": "^10.1.4", "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", @@ -20923,9 +20326,9 @@ } }, "node_modules/stylelint-config-standard": { - "version": "39.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-39.0.0.tgz", - "integrity": "sha512-JabShWORb8Bmc1A47ZyJstran60P3yUdI1zWMpGYPeFiC6xzHXJMkpKAd8EjIhq3HPUplIWWMDJ/xu0AiPd+kA==", + "version": "39.0.1", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-39.0.1.tgz", + "integrity": "sha512-b7Fja59EYHRNOTa3aXiuWnhUWXFU2Nfg6h61bLfAb5GS5fX3LMUD0U5t4S8N/4tpHQg3Acs2UVPR9jy2l1g/3A==", "dev": true, "funding": [ { @@ -21109,15 +20512,15 @@ } }, "node_modules/stylelint/node_modules/flat-cache": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.13.tgz", - "integrity": "sha512-gmtS2PaUjSPa4zjObEIn4WWliKyZzYljgxODBfxugpK6q6HU9ClXzgCJ+nlcPKY9Bt090ypTOLIFWkV0jbKFjw==", + "version": "6.1.18", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.18.tgz", + "integrity": "sha512-JUPnFgHMuAVmLmoH9/zoZ6RHOt5n9NlUw/sDXsTbROJ2SFoS2DS4s+swAV6UTeTbGH/CAsZIE6M8TaG/3jVxgQ==", "dev": true, "license": "MIT", "dependencies": { - "cacheable": "^1.10.4", + "cacheable": "^2.1.0", "flatted": "^3.3.3", - "hookified": "^1.11.0" + "hookified": "^1.12.0" } }, "node_modules/stylelint/node_modules/globby": { @@ -21375,22 +20778,22 @@ } }, "node_modules/taiga-ui": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/taiga-ui/-/taiga-ui-4.52.0.tgz", - "integrity": "sha512-SHpoRjgbjL/RtdnUADEWHp2ZsIapL+jpOKUlFbnzGfroAvpcis5cu4M4OUrCoTfpUZLkdsrGf5YMM5ASwEElRQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/taiga-ui/-/taiga-ui-4.59.0.tgz", + "integrity": "sha512-1BbbvXOHf4hHbqMvDf7V7KtXZR9JbzNW5o0uMkvvExIWy6+kdm5+8ysTlC5E9ynhp0PFrHz2Y9pBjs8ZuhTtAw==", "license": "Apache-2.0", "dependencies": { - "@taiga-ui/cdk": "^4.52.0", + "@taiga-ui/cdk": "^4.59.0", "tslib": ">=2.8.1" }, "peerDependencies": { - "@taiga-ui/cdk": "^4.52.0" + "@taiga-ui/cdk": "^4.59.0" } }, "node_modules/tapable": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.3.tgz", - "integrity": "sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", "dev": true, "license": "MIT", "engines": { @@ -21588,14 +20991,14 @@ "license": "MIT" }, "node_modules/tinyglobby": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", - "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", "dev": true, "license": "MIT", "dependencies": { - "fdir": "^6.4.4", - "picomatch": "^4.0.2" + "fdir": "^6.5.0", + "picomatch": "^4.0.3" }, "engines": { "node": ">=12.0.0" @@ -21604,6 +21007,19 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tmp": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", @@ -21664,29 +21080,6 @@ "tree-kill": "cli.js" } }, - "node_modules/trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/trim-repeated/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/ts-api-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", @@ -21768,21 +21161,8 @@ "dependencies": { "prelude-ls": "^1.2.1" }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 0.8.0" } }, "node_modules/type-is": { @@ -22123,9 +21503,9 @@ } }, "node_modules/undici-types": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", - "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", "dev": true, "license": "MIT" }, @@ -22154,9 +21534,9 @@ } }, "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", - "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", "dev": true, "license": "MIT", "engines": { @@ -22164,9 +21544,9 @@ } }, "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", "dev": true, "license": "MIT", "engines": { @@ -22213,13 +21593,13 @@ } }, "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, "license": "MIT", "engines": { - "node": ">= 10.0.0" + "node": ">= 4.0.0" } }, "node_modules/unpipe": { @@ -22268,9 +21648,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", + "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", "dev": true, "funding": [ { @@ -22302,8 +21682,9 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "devOptional": true, + "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "punycode": "^2.1.0" } @@ -22312,8 +21693,9 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "devOptional": true, + "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=6" } @@ -22377,9 +21759,9 @@ } }, "node_modules/vite": { - "version": "6.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", - "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "dev": true, "license": "MIT", "peer": true, @@ -22452,10 +21834,250 @@ } } }, + "node_modules/vite/node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz", + "integrity": "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-android-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz", + "integrity": "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.5.tgz", + "integrity": "sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-darwin-x64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz", + "integrity": "sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz", + "integrity": "sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz", + "integrity": "sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz", + "integrity": "sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz", + "integrity": "sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz", + "integrity": "sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz", + "integrity": "sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz", + "integrity": "sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz", + "integrity": "sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz", + "integrity": "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz", + "integrity": "sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz", + "integrity": "sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz", + "integrity": "sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, "node_modules/vite/node_modules/rollup": { - "version": "4.50.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.50.0.tgz", - "integrity": "sha512-/Zl4D8zPifNmyGzJS+3kVoyXeDeT/GrsJM94sACNg9RtUE0hrHa1bNPtRSrfHTMH5HjRzce6K7rlTh3Khiw+pw==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz", + "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==", "dev": true, "license": "MIT", "peer": true, @@ -22470,27 +22092,28 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.50.0", - "@rollup/rollup-android-arm64": "4.50.0", - "@rollup/rollup-darwin-arm64": "4.50.0", - "@rollup/rollup-darwin-x64": "4.50.0", - "@rollup/rollup-freebsd-arm64": "4.50.0", - "@rollup/rollup-freebsd-x64": "4.50.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.50.0", - "@rollup/rollup-linux-arm-musleabihf": "4.50.0", - "@rollup/rollup-linux-arm64-gnu": "4.50.0", - "@rollup/rollup-linux-arm64-musl": "4.50.0", - "@rollup/rollup-linux-loongarch64-gnu": "4.50.0", - "@rollup/rollup-linux-ppc64-gnu": "4.50.0", - "@rollup/rollup-linux-riscv64-gnu": "4.50.0", - "@rollup/rollup-linux-riscv64-musl": "4.50.0", - "@rollup/rollup-linux-s390x-gnu": "4.50.0", - "@rollup/rollup-linux-x64-gnu": "4.50.0", - "@rollup/rollup-linux-x64-musl": "4.50.0", - "@rollup/rollup-openharmony-arm64": "4.50.0", - "@rollup/rollup-win32-arm64-msvc": "4.50.0", - "@rollup/rollup-win32-ia32-msvc": "4.50.0", - "@rollup/rollup-win32-x64-msvc": "4.50.0", + "@rollup/rollup-android-arm-eabi": "4.52.5", + "@rollup/rollup-android-arm64": "4.52.5", + "@rollup/rollup-darwin-arm64": "4.52.5", + "@rollup/rollup-darwin-x64": "4.52.5", + "@rollup/rollup-freebsd-arm64": "4.52.5", + "@rollup/rollup-freebsd-x64": "4.52.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.5", + "@rollup/rollup-linux-arm-musleabihf": "4.52.5", + "@rollup/rollup-linux-arm64-gnu": "4.52.5", + "@rollup/rollup-linux-arm64-musl": "4.52.5", + "@rollup/rollup-linux-loong64-gnu": "4.52.5", + "@rollup/rollup-linux-ppc64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-musl": "4.52.5", + "@rollup/rollup-linux-s390x-gnu": "4.52.5", + "@rollup/rollup-linux-x64-gnu": "4.52.5", + "@rollup/rollup-linux-x64-musl": "4.52.5", + "@rollup/rollup-openharmony-arm64": "4.52.5", + "@rollup/rollup-win32-arm64-msvc": "4.52.5", + "@rollup/rollup-win32-ia32-msvc": "4.52.5", + "@rollup/rollup-win32-x64-gnu": "4.52.5", + "@rollup/rollup-win32-x64-msvc": "4.52.5", "fsevents": "~2.3.2" } }, @@ -22681,6 +22304,44 @@ } } }, + "node_modules/webpack-dev-server/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/webpack-dev-server/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { "version": "2.0.9", "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", @@ -22706,6 +22367,32 @@ } } }, + "node_modules/webpack-dev-server/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/webpack-dev-server/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/webpack-dev-server/node_modules/ws": { "version": "8.18.3", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", diff --git a/package.json b/package.json index 6744801..66fd78f 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "lint": "npm run lint:ts && npm run lint:styles", "format": "prettier --write .", "prepare": "husky", - "deploy": "npm run build:github && npx angular-cli-ghpages --dir=dist/strive", + "deploy": "npm run build:github", "generate:icons": "node scripts/generate-pwa-icons.cjs" }, "type": "module", @@ -70,7 +70,6 @@ "@angular/compiler-cli": "^19.2.0", "@types/jasmine": "~5.1.0", "@types/telegram-web-app": "^9.0.0", - "angular-cli-ghpages": "^1.0.3", "angular-eslint": "20.1.1", "eslint-config-prettier": "^10.1.8", "eslint-import-resolver-typescript": "^3.6.1", diff --git a/src/app/app.component.html b/src/app/app.component.html index 271629d..d944606 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,9 +1,30 @@ -
- - -
- -
-
+ @if (loading()) { +
+
+

Loading...

+
+ } @else if (error()) { +
+
⚠️
+

Something went wrong

+

{{ error() }}

+ +
+ } @else { +
+ + +
+ +
+
+ }
\ No newline at end of file diff --git a/src/app/app.component.scss b/src/app/app.component.scss index 44443b8..3d5b595 100644 --- a/src/app/app.component.scss +++ b/src/app/app.component.scss @@ -65,3 +65,73 @@ padding-bottom: env(safe-area-inset-bottom, 0); } } + +.loading-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + + width: 100%; + height: 100vh; + + background: var(--tui-base-01); +} + +.loading-spinner { + width: 40px; + height: 40px; + margin-bottom: var(--space-md); + border: 3px solid var(--tui-base-03); + border-top: 3px solid var(--tui-primary); + border-radius: 50%; + + animation: spin 1s linear infinite; +} + +.loading-text { + font: var(--tui-font-text-m); + color: var(--tui-text-02); +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +.error-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + + width: 100%; + height: 100vh; + padding: var(--space-lg); + + text-align: center; + + background: var(--tui-base-01); +} + +.error-icon { + margin-bottom: var(--space-md); + font-size: 48px; +} + +.error-title { + margin: 0 0 var(--space-sm) 0; + font: var(--tui-font-heading-4); + color: var(--tui-text-01); +} + +.error-message { + max-width: 400px; + margin: 0 0 var(--space-lg) 0; + font: var(--tui-font-text-m); + color: var(--tui-text-02); +} + +.retry-button { + min-width: 120px; +} diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index e19d324..6046114 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -4,6 +4,7 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { TestBed } from '@angular/core/testing'; import { provideRouter } from '@angular/router'; import { TuiRoot } from '@taiga-ui/core'; +import { of } from 'rxjs'; import { AuthService } from '@/features/auth'; import { TelegramService, ThemeService, SwUpdateService, UserStoreService } from '@/shared'; import { configureZonelessTestingModule } from '@/test-setup'; @@ -48,10 +49,16 @@ describe('AppComponent', () => { swUpdateServiceSpy = jasmine.createSpyObj('SwUpdateService', ['checkForUpdate', 'init']); - const userStoreSpy = jasmine.createSpyObj('UserStoreService', ['clearUser'], { - user: jasmine.createSpy().and.returnValue(null), - isAuthenticated: jasmine.createSpy().and.returnValue(false), - }); + const userStoreSpy = jasmine.createSpyObj( + 'UserStoreService', + ['clearUser', 'fetchUser$', 'initializeFromCache'], + { + user: jasmine.createSpy().and.returnValue(null), + isAuthenticated: jasmine.createSpy().and.returnValue(false), + }, + ); + + userStoreSpy.fetchUser$.and.returnValue(of(null)); configureZonelessTestingModule({ imports: [AppComponent, MockTuiRootComponent], diff --git a/src/app/app.component.ts b/src/app/app.component.ts index a3c6f2f..c67725c 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,14 +1,16 @@ -import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, inject, DestroyRef, signal } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { RouterOutlet } from '@angular/router'; -import { TuiRoot } from '@taiga-ui/core'; +import { TuiRoot, TuiButton } from '@taiga-ui/core'; +import { forkJoin, finalize, catchError, of } from 'rxjs'; -import { TelegramService, ThemeService, SwUpdateService } from '@/shared'; +import { TelegramService, ThemeService, SwUpdateService, UserStoreService } from '@/shared'; import { NavigationComponent } from '@/widgets'; import type { OnInit } from '@angular/core'; @Component({ selector: 'app-root', - imports: [RouterOutlet, NavigationComponent, TuiRoot], + imports: [RouterOutlet, NavigationComponent, TuiRoot, TuiButton], templateUrl: './app.component.html', styleUrl: './app.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, @@ -17,10 +19,42 @@ export class AppComponent implements OnInit { private readonly telegramService = inject(TelegramService); private readonly themeService = inject(ThemeService); private readonly swUpdateService = inject(SwUpdateService); + private readonly userStore = inject(UserStoreService); + private readonly destroyRef = inject(DestroyRef); + + readonly loading = signal(true); + readonly error = signal(null); ngOnInit(): void { + this.initializeApp(); + } + + private initializeApp(): void { + this.loading.set(true); + this.error.set(null); + this.telegramService.webApp.ready(); this.themeService.initialize(); this.swUpdateService.init(); + + const initializationTasks = [this.userStore.fetchUser$()]; + + forkJoin(initializationTasks) + .pipe( + catchError((error) => { + console.error('Initialization failed:', error); + this.error.set('Failed to load application data. Please try again.'); + return of(null); + }), + finalize(() => { + this.loading.set(false); + }), + takeUntilDestroyed(this.destroyRef), + ) + .subscribe(); + } + + retryInitialization(): void { + this.initializeApp(); } } diff --git a/src/app/app.config.ts b/src/app/app.config.ts index e7fd971..6bb3aa3 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -1,10 +1,10 @@ -import { provideHttpClient, withInterceptors } from '@angular/common/http'; +import { provideHttpClient, withInterceptors, withFetch } from '@angular/common/http'; import { isDevMode, provideExperimentalZonelessChangeDetection } from '@angular/core'; import { provideRouter } from '@angular/router'; import { provideServiceWorker } from '@angular/service-worker'; import { provideEventPlugins } from '@taiga-ui/event-plugins'; import { routes } from '@/app/app.routes'; -import { authInterceptor } from './interceptors/auth.interceptor'; +import { authInterceptor } from '@/app/interceptors'; import { credentialsInterceptor } from './interceptors/credentials.interceptor'; import type { ApplicationConfig } from '@angular/core'; @@ -12,7 +12,7 @@ export const appConfig: ApplicationConfig = { providers: [ provideExperimentalZonelessChangeDetection(), provideRouter(routes), - provideHttpClient(withInterceptors([authInterceptor, credentialsInterceptor])), + provideHttpClient(withInterceptors([authInterceptor, credentialsInterceptor]), withFetch()), provideServiceWorker('ngsw-worker.js', { enabled: !isDevMode(), registrationStrategy: 'registerImmediately', diff --git a/src/app/interceptors/auth.interceptor.spec.ts b/src/app/interceptors/auth.interceptor.spec.ts index 3ab41f3..61fd69b 100644 --- a/src/app/interceptors/auth.interceptor.spec.ts +++ b/src/app/interceptors/auth.interceptor.spec.ts @@ -19,6 +19,7 @@ describe('authInterceptor', () => { 'getAccessToken', 'setAccessToken', 'refreshToken$', + 'getTokenInfo', ]); const routerSpy = jasmine.createSpyObj('Router', ['navigate']); @@ -53,6 +54,7 @@ describe('authInterceptor', () => { it('should not add authorization header when no token', () => { authService.getAccessToken.and.returnValue(null); + authService.getTokenInfo.and.returnValue(null); http.get('/api/protected').subscribe(); @@ -62,6 +64,7 @@ describe('authInterceptor', () => { it('should handle non-401 errors without refresh', (done) => { authService.getAccessToken.and.returnValue('test-token'); + authService.getTokenInfo.and.returnValue(null); http.get('/api/protected').subscribe({ next: () => done(), @@ -80,6 +83,7 @@ describe('authInterceptor', () => { router.navigate.and.returnValue(Promise.resolve(true)); authService.getAccessToken.and.returnValue('test-token'); + authService.getTokenInfo.and.returnValue(null); authService.refreshToken$.and.returnValue(of(false)); http.get('/api/protected').subscribe({ @@ -98,6 +102,7 @@ describe('authInterceptor', () => { const addPendingRequestSpy = spyOn(refreshManager, 'addPendingRequest').and.callThrough(); authService.getAccessToken.and.returnValue('test-token'); + authService.getTokenInfo.and.returnValue(null); authService.refreshToken$.and.returnValue(of(true)); refreshManager.setRefreshInProgress(true); diff --git a/src/app/interceptors/auth.interceptor.ts b/src/app/interceptors/auth.interceptor.ts index e5e217c..c3ce97a 100644 --- a/src/app/interceptors/auth.interceptor.ts +++ b/src/app/interceptors/auth.interceptor.ts @@ -1,7 +1,7 @@ import { inject } from '@angular/core'; import { Router } from '@angular/router'; import { catchError, switchMap, throwError, defer, finalize, Observable } from 'rxjs'; -import { AuthService } from '@/features/auth'; +import { AuthService, type TokenInfo } from '@/features/auth'; import { TokenRefreshManager } from './token-refresh-manager'; import type { @@ -33,7 +33,8 @@ const handle401Error = ( return defer(() => { return new Observable>>((subscriber) => { refreshManager.addPendingRequest(() => { - subscriber.next(next(req)); + const authReq = createAuthRequest(req, authService); + subscriber.next(next(authReq)); subscriber.complete(); }); }); @@ -46,7 +47,8 @@ const handle401Error = ( switchMap((success) => { if (success) { refreshManager.processPendingRequests(); - return next(req); + const authReq = createAuthRequest(req, authService); + return next(authReq); } else { refreshManager.clearPendingRequests(); logout(router); @@ -64,6 +66,36 @@ const handle401Error = ( ); }; +const isTokenExpiringSoon = (tokenInfo: TokenInfo | null, minutesBeforeExpiry = 5): boolean => { + if (!tokenInfo) { + return false; + } + + try { + const now = new Date(); + const timeUntilExpiry = tokenInfo.expiresAt.getTime() - now.getTime(); + const minutesInMilliseconds = minutesBeforeExpiry * 60 * 1000; + + return timeUntilExpiry <= minutesInMilliseconds && timeUntilExpiry > 0; + } catch { + return true; + } +}; + +const createAuthRequest = ( + req: HttpRequest, + authService: AuthService, +): HttpRequest => { + const tokenInfo = authService.getTokenInfo(); + return tokenInfo + ? req.clone({ + setHeaders: { + Authorization: `Bearer ${tokenInfo.token}`, + }, + }) + : req; +}; + export const authInterceptor: HttpInterceptorFn = ( req: HttpRequest, next: HttpHandlerFn, @@ -75,16 +107,25 @@ export const authInterceptor: HttpInterceptorFn = ( const authService = inject(AuthService); const router = inject(Router); - const accessToken = authService.getAccessToken(); - if (!accessToken) { - return next(req); + const tokenInfo = authService.getTokenInfo(); + + if (isTokenExpiringSoon(tokenInfo, 5)) { + const refreshManager = TokenRefreshManager.getInstance(); + + if (!refreshManager.isRefreshInProgress) { + refreshManager.setRefreshInProgress(true); + authService + .refreshToken$() + .pipe( + finalize(() => { + refreshManager.setRefreshInProgress(false); + }), + ) + .subscribe(); + } } - const authReq = req.clone({ - setHeaders: { - Authorization: `Bearer ${accessToken}`, - }, - }); + const authReq = createAuthRequest(req, authService); return next(authReq).pipe( catchError((error: HttpErrorResponse) => { diff --git a/src/app/interceptors/credentials.interceptor.ts b/src/app/interceptors/credentials.interceptor.ts index 9af3365..58b73ce 100644 --- a/src/app/interceptors/credentials.interceptor.ts +++ b/src/app/interceptors/credentials.interceptor.ts @@ -10,7 +10,7 @@ export const credentialsInterceptor: HttpInterceptorFn = ( req: HttpRequest, next: HttpHandlerFn, ): Observable> => { - if (req.withCredentials === true) { + if (req.withCredentials) { return next(req); } @@ -20,6 +20,5 @@ export const credentialsInterceptor: HttpInterceptorFn = ( 'Content-Type': 'application/json', }, }); - return next(modifiedReq); }; diff --git a/src/entities/user/ui/user-menu/user-menu.component.html b/src/entities/user/ui/user-menu/user-menu.component.html index bc23475..e4a3160 100644 --- a/src/entities/user/ui/user-menu/user-menu.component.html +++ b/src/entities/user/ui/user-menu/user-menu.component.html @@ -1,8 +1,8 @@
- - +
- +
- - -