diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 00000000..9feaf3f2 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,54 @@ +name: Deploy Docs + +on: + push: + branches: + - develop + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: true + +jobs: + build-and-deploy: + name: Build & Deploy Docs + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Install docs dependencies + working-directory: docs-site + run: pnpm install --ignore-workspace --frozen-lockfile + + - name: Build docs site + working-directory: docs-site + run: pnpm build + + - name: Setup Pages + uses: actions/configure-pages@v5 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: docs-site/build + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index 882d635d..b689aa6a 100644 --- a/.gitignore +++ b/.gitignore @@ -116,6 +116,7 @@ dist # Docusaurus cache and generated files .docusaurus +docs-site/build/ # Serverless directories .serverless/ @@ -157,3 +158,5 @@ vitest.config.*.timestamp* .worktrees/ /apps/tracker/src/i18n-types/tracker-resources.ts /sample-translations/mock-design-system/ +/.playwright-cli/ +/.playwright/ diff --git a/.lingo-tracker.json b/.lingo-tracker.json index 9e7dbc22..5b455fb6 100644 --- a/.lingo-tracker.json +++ b/.lingo-tracker.json @@ -2,20 +2,52 @@ "exportFolder": "dist/lingo-export", "importFolder": "dist/lingo-import", "baseLocale": "en", - "locales": ["en", "fr-ca", "es", "de", "ja"], + "locales": [ + "en", + "fr-ca", + "es", + "ru", + "de", + "ja" + ], "collections": { "TestDataPlayground": { "translationsFolder": "sample-translations/playground", - "locales": ["en", "fr-ca", "es", "de", "ja"] + "locales": [ + "en", + "fr-ca", + "es", + "de", + "ja" + ] }, "trackerResources": { "translationsFolder": "apps/tracker/src/i18n", - "locales": ["en", "es", "fr-ca"] + "locales": [ + "en", + "es", + "fr-ca", + "ru", + "ja", + "de" + ] }, "mockDesignSystem": { "translationsFolder": "sample-translations/mock-design-system", "importFolder": "dist/ds-translations", - "locales": ["ar", "de", "es", "fr-ca", "fr-fr", "is", "ja", "ko", "nl", "pt-br", "sv"] + "locales": [ + "ar", + "de", + "es", + "fr-ca", + "fr-fr", + "is", + "ja", + "ko", + "nl", + "pt-br", + "sv" + ] } }, "translation": { @@ -42,4 +74,4 @@ "typeDistFile": "./apps/tracker/src/i18n-types/tracker-resources.ts" } } -} +} \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md index ae9fb2b8..634d4993 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -86,7 +86,7 @@ libs/ ### Application Responsibilities -- **CLI** (`apps/cli`): Commands for init, add-collection, delete-collection, add-resource. Supports both interactive (TTY) and non-interactive (CI/CD) modes. +- **CLI** (`apps/cli`): Commands for init, add-collection, delete-collection, add-resource, edit-resource, delete-resource, move, normalize, bundle, export, import, validate, find-similar, install-skill. Supports both interactive (TTY) and non-interactive (CI/CD) modes. - **API** (`apps/api`): REST endpoints at `/api/*`, serves static Tracker UI, uses mappers to convert between core domain models and DTOs. - **Tracker UI** (`apps/tracker`): Angular app with Material UI for browsing/managing translations, uses NgRx Signals for state management. @@ -154,6 +154,12 @@ export class ExampleComponent implements OnInit { } ``` +### TypeScript Safety + +- **No non-null assertions**: Never use the `!` operator. The linter (`lint/style/noNonNullAssertion`) forbids it. + - In production code: use an explicit null-guard (`if (!x) return;` or `if (!x) throw`) before accessing the value + - In tests: use `expect(value).toBeDefined()` followed by optional chaining (`value?.property`) for subsequent assertions + ### Code Organization - **Domain Logic** (`@simoncodes-ca/domain`): Pure business logic with **zero Node.js dependencies** — importable by all apps including the browser-based Tracker UI. This is where platform-agnostic logic belongs: key validation/parsing, translation status helpers, ICU↔Transloco format conversion, validation utilities (locale, key length, duplicates, hierarchical conflicts), and shared types (`TranslationStatus`, `LocaleMetadata`). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 42d640a9..d1e781c1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -111,6 +111,16 @@ This project uses [Conventional Commits](https://www.conventionalcommits.org/). - **DTOs**: API contracts are defined in `libs/data-transfer`. - **Testing**: Vitest for unit tests. +## Contributing to Documentation + +The docs site lives in `docs-site/` and is built with [Docusaurus](https://docusaurus.io/). To run it locally: + +```bash +pnpm run docs:dev +``` + +Documentation source files are located under `docs-site/src/pages/`. Add or edit pages there and open a pull request as you would for any other change. + ## Questions? Open an [issue](https://github.com/simoncodes-ca/lingo-tracker/issues) and we'll be happy to help. diff --git a/README.md b/README.md index 133d6492..30270df0 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ npx lingo-tracker validate npx lingo-tracker-app ``` -Check the [getting started guide](docs/getting-started.md) for detailed setup instructions, or the full [CLI reference](docs/cli.md) for all available commands. +Check the [documentation site](https://simoncodes-ca.github.io/lingo-tracker/), the [getting started guide](docs/getting-started.md) for detailed setup instructions, or the full [CLI reference](docs/cli.md) for all available commands. ## Roadmap diff --git a/ai/diagrams/apps.md b/ai/diagrams/apps.md deleted file mode 100644 index 240cfecc..00000000 --- a/ai/diagrams/apps.md +++ /dev/null @@ -1,80 +0,0 @@ -# LingoTracker Monorepo Architecture - -## Overall Monorepo Structure - -```mermaid -graph TB - subgraph Applications["📱 Applications"] - CLI["apps/cli
CLI Interface
(Commander, Node.js)"] - API["apps/api
REST API
(NestJS, Express)"] - TRACKER["apps/tracker
Web UI
(Angular 20, Material)"] - end - - subgraph Libraries["📚 Libraries"] - CORE["libs/core
Core Business Logic"] - DATATRANSFER["libs/data-transfer
DTOs & Contracts"] - end - - subgraph CoreModules["🔧 Core Modules"] - CONFIG["config/
Configuration"] - RESOURCE["resource/
CRUD & Metadata"] - FILEIO["file-io/
File Operations"] - FOLDER["folder/
Folder Management"] - BUNDLE["bundle/
Bundles & Types"] - VALIDATE["validate/
Validation"] - EXPORT["export/
Export (XLIFF, JSON)"] - IMPORT["import/
Import (XLIFF, JSON)"] - NORMALIZE["normalize/
Normalization"] - ERRORS["errors/
Error Handling"] - end - - subgraph SharedDTOs["📦 Shared Data Contracts"] - DTO_COLLECTION["Collection DTOs
CreateCollection, UpdateCollection"] - DTO_RESOURCE["Resource DTOs
CreateResource, UpdateResource, DeleteResource"] - DTO_FOLDER["Folder DTOs
CreateFolder, MoveResource"] - DTO_SEARCH["Search DTOs
SearchResult, SearchTranslations"] - DTO_TREE["Tree DTOs
ResourceTree, TreeStatusResponse"] - DTO_CONFIG["Config DTOs
Collection, Global Config"] - end - - %% Application Dependencies - CLI -->|imports| CORE - CLI -->|uses| DATATRANSFER - API -->|imports| CORE - API -->|imports| DATATRANSFER - TRACKER -->|imports| DATATRANSFER - - %% Core Module Structure - CORE --> CONFIG - CORE --> RESOURCE - CORE --> FILEIO - CORE --> FOLDER - CORE --> BUNDLE - CORE --> VALIDATE - CORE --> EXPORT - CORE --> IMPORT - CORE --> NORMALIZE - CORE --> ERRORS - - %% Internal Core Dependencies - RESOURCE -->|uses| CONFIG - RESOURCE -->|uses| FILEIO - RESOURCE -->|uses| ERRORS - BUNDLE -->|uses| RESOURCE - VALIDATE -->|uses| RESOURCE - EXPORT -->|uses| RESOURCE - IMPORT -->|uses| RESOURCE - NORMALIZE -->|uses| RESOURCE - - %% DTO Dependencies - DATATRANSFER --> DTO_COLLECTION - DATATRANSFER --> DTO_RESOURCE - DATATRANSFER --> DTO_FOLDER - DATATRANSFER --> DTO_SEARCH - DATATRANSFER --> DTO_TREE - DATATRANSFER --> DTO_CONFIG - - style Applications fill:#e1f5ff - style Libraries fill:#f3e5f5 - style CoreModules fill:#fff3e0 - style SharedDTOs fill:#e8f5e9 diff --git a/ai/diagrams/ui-routes.md b/ai/diagrams/ui-routes.md deleted file mode 100644 index 6523175b..00000000 --- a/ai/diagrams/ui-routes.md +++ /dev/null @@ -1,470 +0,0 @@ -# Angular Routing & Data Flow - -## Route Structure - -```mermaid -graph TB - ROOT["/ ROOT"] - - REDIRECT["Redirect to /collections"] - - COLLECTIONS_ROUTE["/collections"] - BROWSER_ROUTE["/browser/:collectionName"] - - ROOT -->|redirects| REDIRECT - REDIRECT --> COLLECTIONS_ROUTE - ROOT -->|navigates| BROWSER_ROUTE - COLLECTIONS_ROUTE -->|navigates| BROWSER_ROUTE - - style ROOT fill:#e1f5ff - style COLLECTIONS_ROUTE fill:#f3e5f5 - style BROWSER_ROUTE fill:#e8f5e9 -``` - -## Route: /collections - Collections Manager - -```mermaid -graph TB - subgraph Route["Route: /collections"] - COMPONENT["CollectionsManager
(Main Component)"] - end - - subgraph DataStore["🏪 State Management"] - COLLECTIONS_STORE["CollectionsStore"] - STATE["State:
• config
• isLoading
• error"] - COMPUTED["Computed:
• collectionEntries
• collectionEntriesWithLocales
• hasCollections"] - end - - subgraph Services["🔌 Services"] - COLLECTIONS_API["CollectionsApiService"] - HTTP["HttpClient"] - end - - subgraph UITree["📊 Component Tree"] - COMPONENT - HEADER["AppHeader
(Theme Control)"] - GRID["Collection Grid
(Material Table)"] - DIALOG["CollectionFormDialog
(Create/Edit)"] - CONFIRM["ConfirmationDialog
(Delete)"] - end - - subgraph DataFlow["📡 Data Flow"] - LOAD["1. Load collections on init"] - DISPLAY["2. Display in grid from computed"] - CREATE["3. User action: Create/Edit/Delete"] - CALL["4. Call API"] - UPDATE["5. Store updates state"] - REFRESH["6. UI re-renders via signals"] - end - - Route --> COMPONENT - COMPONENT -->|injects| COLLECTIONS_STORE - COMPONENT -->|injects| MAT_DIALOG["MatDialog"] - - COLLECTIONS_STORE --> STATE - COLLECTIONS_STORE --> COMPUTED - COLLECTIONS_STORE -->|uses| COLLECTIONS_API - - COLLECTIONS_API -->|HTTP GET| HTTP - HTTP -->|calls| API["API: GET /api/config"] - - COMPONENT --> UITree - UITree --> HEADER - UITree --> GRID - UITree -.->|launch| DIALOG - UITree -.->|launch| CONFIRM - - DIALOG -->|create/update| COLLECTIONS_API - CONFIRM -->|delete| COLLECTIONS_API - - COLLECTIONS_API -->|patchState| COLLECTIONS_STORE - COLLECTIONS_STORE -->|computed signals| COMPONENT - COMPONENT -->|bound to template| GRID - - LOAD --> DISPLAY --> CREATE --> CALL --> UPDATE --> REFRESH - - style Route fill:#f3e5f5 - style DataStore fill:#c8e6c9 - style Services fill:#bbdefb - style UITree fill:#ffe0b2 - style DataFlow fill:#f8bbd0 -``` - -## Route: /browser/:collectionName - Translation Browser - -```mermaid -graph TB - subgraph Route["Route: /browser/:collectionName"] - COMPONENT["TranslationBrowser
(Master-Detail Layout)"] - end - - subgraph DataStore["🏪 State Management"] - COLLECTIONS_STORE["CollectionsStore"] - BROWSER_STORE["BrowserStore"] - BROWSER_STATE["Browser State:
• selectedCollection
• currentFolderPath
• translations[]
• searchQuery
• densityMode
• selectedLocales
• selectedStatuses
... (60+ properties)"] - BROWSER_COMPUTED["Computed:
• breadcrumbs()
• filteredFolders()
• sortedTranslations()
• displayedTranslations()
• isCacheReady()
• translationCount()"] - end - - subgraph Services["🔌 Services"] - BROWSER_API["BrowserApiService"] - COLLECTIONS_API["CollectionsApiService"] - HTTP["HttpClient"] - LOCAL_STORAGE["localStorage
(View Prefs)"] - end - - subgraph Initialization["🚀 Initialization (OnInit)"] - STEP1["1. Extract collectionName from route"] - STEP2["2. Load collection config from CollectionsStore"] - STEP3["3. Restore view preferences from localStorage"] - STEP4["4. Initialize BrowserStore with collection"] - STEP5["5. Load root folders"] - STEP6["6. Trigger cache status check"] - end - - subgraph Sidebar["📁 Sidebar Components"] - HEADER["SidebarHeader"] - SEARCH["TranslationSearch
(Global search input)"] - FOLDER_TREE["FolderTree
(Hierarchical navigation)"] - LOCALE_FILTER["LocaleFilter
(Multi-select locales)"] - STATUS_FILTER["StatusFilter
(Filter by status)"] - end - - subgraph MainContent["📝 Main Content Components"] - MAIN_HEADER["TranslationMainHeader
(Breadcrumb, controls)"] - LIST["TranslationList
(Virtual scrolled list)"] - ITEMS["TranslationItem[]"] - end - - subgraph DataLoadingFlow["📡 Data Loading Patterns"] - PATTERN1["Pattern 1: Folder Navigation
User clicks folder → loadFolderChildren()
→ API: GET /resources/tree?path=
→ Update translations[] → Display"] - - PATTERN2["Pattern 2: Search
User types search → searchTranslations(query)
→ API: GET /resources/search?q=
→ isSearchMode = true
→ Display searchResults[]"] - - PATTERN3["Pattern 3: Filter
User selects filter → setSelectedLocales/Statuses()
→ filteredFolders() recomputes
→ displayedTranslations() filtered → Display"] - - PATTERN4["Pattern 4: Edit/Create
User opens dialog → TranslationEditorDialog
→ similarResourcesWarning searches
→ Submit → API: POST/PATCH /resources
→ patchState BrowserStore
→ Display updates via signals"] - end - - Route --> COMPONENT - COMPONENT -->|injects| COLLECTIONS_STORE - COMPONENT -->|injects| BROWSER_STORE - COMPONENT -->|effect| STEP1 - - STEP1 --> STEP2 - STEP2 --> STEP3 - STEP3 --> STEP4 - STEP4 --> STEP5 - STEP5 --> STEP6 - - BROWSER_STORE --> BROWSER_STATE - BROWSER_STORE --> BROWSER_COMPUTED - BROWSER_STORE -->|uses| BROWSER_API - COLLECTIONS_STORE -->|uses| COLLECTIONS_API - - BROWSER_API -->|HTTP| HTTP - COLLECTIONS_API -->|HTTP| HTTP - BROWSER_STORE -->|auto-save| LOCAL_STORAGE - LOCAL_STORAGE -->|auto-restore| BROWSER_STORE - - COMPONENT --> Sidebar - COMPONENT --> MainContent - - Sidebar --> SEARCH - Sidebar --> FOLDER_TREE - Sidebar --> LOCALE_FILTER - Sidebar --> STATUS_FILTER - - MainContent --> MAIN_HEADER - MainContent --> LIST - LIST --> ITEMS - - SEARCH -->|updates| BROWSER_STORE - FOLDER_TREE -->|selectFolder()| BROWSER_STORE - LOCALE_FILTER -->|setSelectedLocales()| BROWSER_STORE - STATUS_FILTER -->|setSelectedStatuses()| BROWSER_STORE - - BROWSER_COMPUTED -->|signals| ITEMS - BROWSER_STATE -->|signals| LIST - - Sidebar -.->|uses| PATTERN1 - Sidebar -.->|uses| PATTERN2 - ITEMS -.->|uses| PATTERN3 - ITEMS -.->|uses| PATTERN4 - - style Route fill:#e8f5e9 - style DataStore fill:#c8e6c9 - style Services fill:#bbdefb - style Initialization fill:#fff9c4 - style Sidebar fill:#f1f8e9 - style MainContent fill:#fce4ec - style DataLoadingFlow fill:#ede7f6 -``` - -## Component Tree & Service Injection - Sidebar - -```mermaid -graph TB - BROWSER["TranslationBrowser
(CollectionsStore, BrowserStore)"] - - SIDEBAR["Sidebar"] - HEADER["SidebarHeader
(BrowserStore)"] - SEARCH["TranslationSearch
(BrowserStore)"] - FOLDER_TREE["FolderTree
(BrowserStore)"] - LOCALE_FILTER["LocaleFilter
(BrowserStore)"] - STATUS_FILTER["StatusFilter
(BrowserStore)"] - - FOLDER_NODE["FolderNode (Recursive)
(BrowserStore, emit select)"] - INLINE_INPUT["InlineFolderInput
(BrowserStore)"] - - BROWSER --> SIDEBAR - SIDEBAR --> HEADER - SIDEBAR --> SEARCH - SIDEBAR --> FOLDER_TREE - SIDEBAR --> LOCALE_FILTER - SIDEBAR --> STATUS_FILTER - - FOLDER_TREE --> FOLDER_NODE - FOLDER_NODE -->|recursive| FOLDER_NODE - FOLDER_NODE --> INLINE_INPUT - - %% Signal Bindings - HEADER -->|reads| BREADCRUMBS["breadcrumbs()"] - HEADER -->|reads| COLLECTION["selectedCollection"] - - SEARCH -->|reads| SEARCH_Q["searchQuery"] - SEARCH -->|writes| "searchTranslations()" - - FOLDER_TREE -->|reads| FOLDERS["rootFolders"] - FOLDER_TREE -->|reads| EXPANDED["expandedFolders"] - FOLDER_TREE -->|reads| FILTER["folderTreeFilter"] - FOLDER_TREE -->|writes| "selectFolder()" - - FOLDER_NODE -->|reads| CHILDREN["children (computed)"] - FOLDER_NODE -->|reads| IS_SELECTED["isSelected (computed)"] - FOLDER_NODE -->|emit| SELECT_EVENT["selectFolder()"] - - INLINE_INPUT -->|writes| "createFolder()" - - LOCALE_FILTER -->|reads| LOCALES["filteredLocales()"] - LOCALE_FILTER -->|reads| SEL_LOC["selectedLocales"] - LOCALE_FILTER -->|writes| "setSelectedLocales()" - - STATUS_FILTER -->|reads| SEL_STATUS["selectedStatuses"] - STATUS_FILTER -->|writes| "setSelectedStatuses()" - - style BROWSER fill:#e8f5e9 - style SIDEBAR fill:#f1f8e9 - style FOLDER_TREE fill:#81c784 - style FOLDER_NODE fill:#66bb6a - style HEADER fill:#a5d6a7 - style SEARCH fill:#c8e6c9 - style LOCALE_FILTER fill:#a1887f - style STATUS_FILTER fill:#a1887f -``` - -## Component Tree & Service Injection - Main Content - -```mermaid -graph TB - BROWSER["TranslationBrowser
(CollectionsStore, BrowserStore)"] - - MAIN_CONTENT["Main Content Area"] - MAIN_HEADER["TranslationMainHeader"] - LIST["TranslationList
(BrowserStore, BrowserApiService)"] - ITEM["TranslationItem
(BrowserStore, MatDialog)"] - - ITEM_HEADER["ItemHeader
(Display key, status)"] - ITEM_LOCALES["ItemLocales
(Display translations)"] - ITEM_CONTROLS["ItemCompactControls
(Action buttons)"] - ITEM_ROLLUP["TranslationRollup
(Aggregated locale state)"] - - DIALOGS["Dialogs (lazy-loaded)"] - EDITOR_DIALOG["TranslationEditorDialog
(Create/Edit, BrowserApiService)"] - MOVE_DIALOG["MoveResourceDialog
(BrowserApiService)"] - CONFIRM_DIALOG["ConfirmationDialog
(Delete confirmation)"] - - POPOVERS["Popovers (context menus)"] - COMMENT_POPOVER["CommentPopover
(View/edit comments)"] - TAG_POPOVER["TagListPopover
(View/edit tags)"] - - PIPES["Pipes"] - HIGHLIGHT_PIPE["HighlightPipe
(Search highlighting)"] - TRUNCATE_PIPE["TruncateKeyPipe
(Key truncation)"] - - UI_COMPONENTS["UI Components"] - INDEXING_OVERLAY["IndexingOverlay
(Full-screen loading)"] - SEARCH_INPUT["SearchInput
(Reusable search)"] - TAG_LIST["TagList
(Display tags)"] - - BROWSER --> MAIN_CONTENT - MAIN_CONTENT --> MAIN_HEADER - MAIN_CONTENT --> LIST - - LIST --> ITEM - ITEM --> ITEM_HEADER - ITEM --> ITEM_LOCALES - ITEM --> ITEM_CONTROLS - ITEM --> ITEM_ROLLUP - - ITEM -.->|launch| DIALOGS - DIALOGS --> EDITOR_DIALOG - DIALOGS --> MOVE_DIALOG - DIALOGS --> CONFIRM_DIALOG - - ITEM_HEADER -.->|show| POPOVERS - POPOVERS --> COMMENT_POPOVER - POPOVERS --> TAG_POPOVER - - ITEM_HEADER -->|use| HIGHLIGHT_PIPE - ITEM_HEADER -->|use| TRUNCATE_PIPE - - MAIN_CONTENT -.->|show| UI_COMPONENTS - UI_COMPONENTS --> INDEXING_OVERLAY - UI_COMPONENTS --> SEARCH_INPUT - UI_COMPONENTS --> TAG_LIST - - %% Signal Bindings for List - LIST -->|reads| DISPLAYED["displayedTranslations()"] - LIST -->|reads| SORTED["sortedTranslations()"] - LIST -->|reads| COUNT["translationCount"] - LIST -->|reads| LOADING["isTranslationsLoading"] - - %% Signal Bindings for Items - ITEM -->|reads| KEY["key"] - ITEM -->|reads| BASE_VALUE["baseValue"] - ITEM -->|reads| STATUS["status"] - ITEM -->|reads| TRANSLATIONS["translations { [locale]: value }"] - ITEM -->|reads| SEARCH_Q["searchQuery (for highlighting)"] - ITEM -->|reads| COMPACT_LOCALE["compactLocale (single-locale mode)"] - - %% API Calls - EDITOR_DIALOG -->|POST/PATCH| "BrowserApiService.createResource() / updateResource()" - MOVE_DIALOG -->|PATCH| "BrowserApiService.moveResource()" - CONFIRM_DIALOG -->|DELETE| "BrowserApiService.deleteResource()" - - %% State Updates - "BrowserApiService calls" -->|patchState| "BrowserStore" - "BrowserStore" -->|recompute| "displayedTranslations()" - "displayedTranslations()" -->|signal| ITEM - - style BROWSER fill:#e8f5e9 - style MAIN_CONTENT fill:#fce4ec - style LIST fill:#f48fb1 - style ITEM fill:#ec407a - style ITEM_HEADER fill:#e91e63 - style ITEM_LOCALES fill:#ad1457 - style ITEM_CONTROLS fill:#c2185b - style DIALOGS fill:#ede7f6 - style POPOVERS fill:#f3e5f5 - style PIPES fill:#fff9c4 - style UI_COMPONENTS fill:#e0f2f1 -``` - -## State Update Flow - Creating a Translation - -```mermaid -sequenceDiagram - participant User as User - participant Dialog as TranslationEditorDialog - participant Store as BrowserStore - participant API as BrowserApiService - participant Server as API Server - participant List as TranslationList - - User->>Dialog: Click "Create" button - Dialog->>Dialog: Fill form (key, base value, locales) - User->>Dialog: Submit form - Dialog->>Store: showSimilarWarning() search - Store->>API: searchTranslations(query) - API->>Server: GET /resources/search?q= - Server-->>API: results[] - API-->>Dialog: Display warning - - User->>Dialog: Confirm creation - Dialog->>API: createResource(dto) - API->>Server: POST /collections/{name}/resources - Server->>Server: Create resource file - Server-->>API: { id, key, created_at, ... } - - API->>Store: patchState({ translations: [..., newResource] }) - Store->>Store: Recompute displayedTranslations() - Store->>List: Signal updated - List->>List: Re-render with new item - List-->>User: ✅ New item visible in list - - Dialog->>Dialog: Close - Dialog-->>User: Success notification -``` - -## State Update Flow - Searching Translations - -```mermaid -sequenceDiagram - participant User as User - participant Search as TranslationSearch - participant Store as BrowserStore - participant API as BrowserApiService - participant Server as API Server - participant List as TranslationList - - User->>Search: Type search query "button" - Search->>Store: debounce 300ms (searchQuery) - Store->>Store: isSearchMode = true - Store->>Store: Trigger searchTranslations() rxMethod - Store->>API: searchTranslations(query) - API->>Server: GET /collections/{name}/resources/search?q=button - Server->>Server: Full-text search across all resources - Server-->>API: searchResults[] - API->>Store: patchState({ searchResults, isSearchLoading: false }) - Store->>Store: Recompute displayedTranslations() from searchResults - Store->>List: Signal updated - List->>List: Re-render filtered items - List-->>User: ✅ Display search results - - User->>Search: Clear search - Search->>Store: searchQuery = "" - Store->>Store: isSearchMode = false - Store->>Store: Recompute displayedTranslations() from currentFolder - List->>List: Re-render folder contents - List-->>User: ✅ Back to folder view -``` - -## Storage & Persistence - -```mermaid -graph TB - subgraph Browser["Browser Storage"] - LOCAL_STORAGE["localStorage"] - end - - subgraph Preferences["View Preferences per Collection"] - DENSITY["densityMode: 'compact' | 'medium' | 'full'"] - LOCALES["selectedLocales: string[]"] - NESTED["showNestedResources: boolean"] - SORT_FIELD["sortField: 'key' | 'status'"] - SORT_DIR["sortDirection: 'asc' | 'desc'"] - STATUSES["selectedStatuses: TranslationStatus[]"] - COMPACT_LOCALE["compactLocale: string"] - MANUAL_CHANGE["compactLocaleManuallyChanged: boolean"] - end - - subgraph Key["Storage Key"] - KEY_FORMAT["lingo-tracker:view-prefs:{collectionName}"] - end - - subgraph Lifecycle["Lifecycle"] - ON_INIT["On route init:
Restore preferences from localStorage"] - ON_CHANGE["On user change:
Auto-save to localStorage"] - ON_SELECT["On collection change:
Restore different collection preferences"] - end - - BrowserStore -->|auto-save| LOCAL_STORAGE - LOCAL_STORAGE -->|stores| Preferences - Preferences -->|uses| KEY_FORMAT - Lifecycle -->|controls| BrowserStore - - style Browser fill:#e0f2f1 - style Preferences fill:#b2dfdb - style Key fill:#80cbc4 - style Lifecycle fill:#4db6ac -``` diff --git a/ai/diagrams/ui.md b/ai/diagrams/ui.md deleted file mode 100644 index c29b962e..00000000 --- a/ai/diagrams/ui.md +++ /dev/null @@ -1,311 +0,0 @@ -# Angular UI Architecture - Components & Services - -## Component Hierarchy - -```mermaid -graph TB - subgraph App["🎯 Root Component"] - ROOT["app.ts
Router Outlet"] - end - - subgraph Collections["📋 Collections Module"] - COLLECTIONS_MGR["CollectionsManager"] - COLLECTION_FORM["CollectionFormDialog"] - end - - subgraph Header["🎨 Top Navigation"] - APP_HEADER["AppHeader"] - THEME_SWITCHER["Theme Control
(Light/Dark/System)"] - end - - subgraph Browser["🌐 Translation Browser"] - BROWSER_ROOT["TranslationBrowser
(Master-Detail Layout)"] - - subgraph Sidebar["📁 Sidebar"] - SIDEBAR_HEADER["SidebarHeader"] - FOLDER_TREE["FolderTree
(Hierarchical Navigation)"] - FOLDER_NODE["FolderNode
(Recursive)"] - INLINE_FOLDER_INPUT["InlineFolderInput
(Create Folder)"] - LOCALE_FILTER["LocaleFilter
(Multi-select)"] - STATUS_FILTER["StatusFilter
(new/translated/stale/verified)"] - TRANSLATION_SEARCH["TranslationSearch
(Global Search)"] - end - - subgraph MainContent["📝 Main Content"] - MAIN_HEADER["TranslationMainHeader
(Breadcrumb & Controls)"] - TRANSLATION_LIST["TranslationList
(Virtual Scrolled List)"] - TRANSLATION_ITEM["TranslationItem"] - ITEM_HEADER["ItemHeader
(Key & Status)"] - ITEM_LOCALES["ItemLocales
(Translated Values)"] - ITEM_CONTROLS["ItemCompactControls"] - TRANSLATION_ROLLUP["TranslationRollup
(Aggregated State)"] - end - - subgraph Dialogs["💬 Modal Dialogs"] - EDITOR_DIALOG["TranslationEditorDialog
(Create/Edit)"] - FOLDER_PICKER["FolderPicker"] - SIMILAR_WARNING["SimilarResourcesWarning"] - MOVE_DIALOG["MoveResourceDialog"] - CONFIRM_DIALOG["ConfirmationDialog
(Delete)"] - end - - subgraph UIComponents["🔘 UI Components"] - COMMENT_POPOVER["CommentPopover"] - TAG_LIST_POPOVER["TagListPopover"] - INDEXING_OVERLAY["IndexingOverlay
(Loading State)"] - SEARCH_INPUT["SearchInput"] - TAG_LIST["TagList"] - end - end - - subgraph Pipes["🔄 Pipes"] - HIGHLIGHT_PIPE["HighlightPipe
(Search Highlighting)"] - TRUNCATE_PIPE["TruncateKeyPipe
(Key Truncation)"] - end - - %% App Structure - ROOT --> Collections - ROOT --> Header - ROOT --> Browser - - %% Header - Header --> APP_HEADER - APP_HEADER --> THEME_SWITCHER - - %% Collections - Collections --> COLLECTIONS_MGR - COLLECTIONS_MGR -.->|launch dialog| COLLECTION_FORM - - %% Browser Structure - Browser --> BROWSER_ROOT - BROWSER_ROOT --> Sidebar - BROWSER_ROOT --> MainContent - BROWSER_ROOT --> Dialogs - BROWSER_ROOT --> UIComponents - - %% Sidebar Components - Sidebar --> SIDEBAR_HEADER - Sidebar --> FOLDER_TREE - FOLDER_TREE --> FOLDER_NODE - FOLDER_NODE -->|recursive| FOLDER_NODE - FOLDER_NODE --> INLINE_FOLDER_INPUT - Sidebar --> LOCALE_FILTER - Sidebar --> STATUS_FILTER - Sidebar --> TRANSLATION_SEARCH - - %% Main Content - MainContent --> MAIN_HEADER - MAIN_HEADER --> TRANSLATION_SEARCH - MAIN_HEADER --> LOCALE_FILTER - MAIN_HEADER --> STATUS_FILTER - MainContent --> TRANSLATION_LIST - TRANSLATION_LIST --> TRANSLATION_ITEM - TRANSLATION_ITEM --> ITEM_HEADER - TRANSLATION_ITEM --> ITEM_LOCALES - TRANSLATION_ITEM --> ITEM_CONTROLS - TRANSLATION_ITEM --> TRANSLATION_ROLLUP - TRANSLATION_ITEM -->|pipes| HIGHLIGHT_PIPE - TRANSLATION_ITEM -->|pipes| TRUNCATE_PIPE - - %% Dialogs - TRANSLATION_ITEM -.->|launch| EDITOR_DIALOG - TRANSLATION_ITEM -.->|launch| MOVE_DIALOG - TRANSLATION_ITEM -.->|launch| CONFIRM_DIALOG - EDITOR_DIALOG --> FOLDER_PICKER - EDITOR_DIALOG --> SIMILAR_WARNING - FOLDER_PICKER --> FOLDER_TREE - - %% UI Components - TRANSLATION_ITEM -.->|popover| COMMENT_POPOVER - TRANSLATION_ITEM -.->|popover| TAG_LIST_POPOVER - UIComponents --> TAG_LIST - Browser -.->|full screen| INDEXING_OVERLAY - - style App fill:#e1f5ff - style Collections fill:#f3e5f5 - style Header fill:#fff3e0 - style Browser fill:#e8f5e9 - style Sidebar fill:#f1f8e9 - style MainContent fill:#fce4ec - style Dialogs fill:#ede7f6 - style UIComponents fill:#e0f2f1 - style Pipes fill:#fff9c4 -``` - -## Service Dependencies - -```mermaid -graph LR - subgraph Stores["🏪 NgRx Signals Stores"] - COLLECTIONS_STORE["CollectionsStore
Collections Management"] - BROWSER_STORE["BrowserStore
Translation Browsing"] - end - - subgraph APIServices["🔌 API Services"] - COLLECTIONS_API["CollectionsApiService"] - BROWSER_API["BrowserApiService"] - end - - subgraph SharedServices["🎯 Shared Services"] - THEME_SERVICE["ThemeService
(Light/Dark/System)"] - TRANSLOCO_SERVICE["TranslocoService
(i18n)"] - TRANSLOCO_LOADER["TranslocoHttpLoader"] - end - - subgraph Infrastructure["⚙️ Angular"] - HTTP_CLIENT["HttpClient"] - ROUTER["Router"] - MAT_DIALOG["MatDialog"] - LOCAL_STORAGE["localStorage"] - end - - %% Store Dependencies - COLLECTIONS_STORE -->|uses| COLLECTIONS_API - BROWSER_STORE -->|uses| BROWSER_API - BROWSER_STORE -->|persists| LOCAL_STORAGE - - %% API Services - COLLECTIONS_API -->|HTTP| HTTP_CLIENT - BROWSER_API -->|HTTP| HTTP_CLIENT - - %% Component Injections - Collections -->|inject| COLLECTIONS_STORE - Browser -->|inject| COLLECTIONS_STORE - Browser -->|inject| BROWSER_STORE - APP_HEADER -->|inject| THEME_SERVICE - TRANSLATION_ITEM -->|inject| MAT_DIALOG - - %% Service Dependencies - THEME_SERVICE -->|reads/writes| LOCAL_STORAGE - THEME_SERVICE -->|listens| window.matchMedia - TRANSLOCO_SERVICE -->|uses| TRANSLOCO_LOADER - TRANSLOCO_LOADER -->|HTTP| HTTP_CLIENT - - style Stores fill:#c8e6c9 - style APIServices fill:#bbdefb - style SharedServices fill:#ffe0b2 - style Infrastructure fill:#f0f4c3 -``` - -## Store Architecture - CollectionsStore - -```mermaid -graph TB - subgraph CollectionsStore["CollectionsStore State"] - State["State:
• config
• isLoading
• error"] - Computed["Computed:
• collectionEntries
• collectionEntriesWithLocales
• hasCollections"] - end - - subgraph CollectionsMethods["Store Methods"] - LoadCollections["loadCollections()"] - CreateCollection["createCollection(name, config)"] - UpdateCollection["updateCollection(name, config)"] - DeleteCollection["deleteCollection(name)"] - end - - State --> Computed - Computed --> CollectionsMethods - - style CollectionsStore fill:#c8e6c9 - style CollectionsMethods fill:#a5d6a7 -``` - -## Store Architecture - BrowserStore - -```mermaid -graph TB - subgraph BrowserState["BrowserStore State"] - CollectionState["📦 Collection State
• selectedCollection
• availableLocales
• baseLocale"] - - FolderState["📁 Folder Navigation
• currentFolderPath
• expandedFolders
• rootFolders
• folderTreeFilter
• isFolderTreeLoading
• isAddingFolder"] - - TranslationState["📝 Translation Display
• translations[]
• isTranslationsLoading
• showNestedResources"] - - SearchState["🔍 Search
• searchQuery
• isSearchMode
• searchResults[]
• isSearchLoading"] - - ViewState["🎨 View Preferences
• densityMode (compact|medium|full)
• compactLocale
• sortField (key|status)
• sortDirection
• selectedStatuses[]"] - - CacheState["💾 Cache & Stats
• cacheStatus
• collectionStats"] - - UIState["🖥️ UI State
• isDisabled
• error
• selectedLocales"] - end - - subgraph BrowserComputed["Computed Signals"] - FilteredFolders["filteredFolders()"] - Breadcrumbs["breadcrumbs()"] - DisplayedTranslations["displayedTranslations()"] - SortedTranslations["sortedTranslations()"] - FilteredLocales["filteredLocales()"] - TranslationCount["translationCount()"] - CacheReady["isCacheReady()"] - CanShowMultiple["canShowMultipleLocales()"] - end - - subgraph BrowserMethods["RxMethods - Async Operations"] - SelectFolder["selectFolder(path)"] - LoadRootFolders["loadRootFolders()"] - LoadFolderChildren["loadFolderChildren(path)"] - SearchTranslations["searchTranslations(query)"] - CheckCache["checkCacheStatus()"] - CreateFolder["createFolder(parentPath, name)"] - SetCollection["setSelectedCollection(name)"] - end - - subgraph BrowserFilters["Sync Methods - Filters & View"] - SetDensity["setDensityMode(mode)"] - SetLocales["setSelectedLocales(locales[])"] - SetStatus["setSelectedStatuses(statuses[])"] - SetSort["setSort(field, direction)"] - ToggleNested["toggleShowNestedResources()"] - SetCompactLocale["setCompactLocale(locale)"] - end - - subgraph Persistence["💾 Persistence"] - SavePrefs["Auto-saved to localStorage
Key: lingo-tracker:view-prefs:{collectionName}"] - RestorePrefs["Auto-restored on collection selection"] - end - - BrowserState --> BrowserComputed - BrowserState --> BrowserMethods - BrowserState --> BrowserFilters - BrowserMethods --> Persistence - BrowserFilters --> Persistence - - style BrowserState fill:#bbdefb - style BrowserComputed fill:#90caf9 - style BrowserMethods fill:#64b5f6 - style BrowserFilters fill:#42a5f5 - style Persistence fill:#f8bbd0 -``` - -## API Endpoints Used by UI - -```mermaid -graph LR - API["NestJS API
/api"] - - Config["GET /config"] - Collections["POST /collections/:name
GET /collections/:name
PUT /collections/:name
DELETE /collections/:name"] - Resources["GET /collections/:name/resources/tree
GET /collections/:name/resources/search
POST /collections/:name/resources
PATCH /collections/:name/resources/:id
DELETE /collections/:name/resources/:id"] - Folders["POST /collections/:name/folders"] - Cache["GET /collections/:name/resources/cache/status"] - - API --> Config - API --> Collections - API --> Resources - API --> Folders - API --> Cache - - Config -.->|CollectionsStore| COLLECTIONS_STORE - Collections -.->|CollectionsStore| COLLECTIONS_STORE - Resources -.->|BrowserStore| BROWSER_STORE - Folders -.->|BrowserStore| BROWSER_STORE - Cache -.->|BrowserStore| BROWSER_STORE - - style API fill:#ffccbc - style Config fill:#ffe0b2 - style Collections fill:#ffd699 - style Resources fill:#ffcc80 - style Folders fill:#ffb74d - style Cache fill:#ffa726 -``` diff --git a/apps/api/src/app/app.module.ts b/apps/api/src/app/app.module.ts index e40d63b1..09b2636e 100644 --- a/apps/api/src/app/app.module.ts +++ b/apps/api/src/app/app.module.ts @@ -6,12 +6,21 @@ import { ConfigController } from './config/config.controller'; import { CollectionsController } from './collections/collections.controller'; import { ResourcesController } from './collections/resources/resources.controller'; import { FoldersController } from './collections/folders/folders.controller'; +import { LocalesController } from './collections/locales/locales.controller'; import { CollectionCacheService } from './cache/collection-cache.service'; +import { TranslationJobService } from './translation-job/translation-job.service'; @Module({ imports: [], - controllers: [AppController, ConfigController, CollectionsController, ResourcesController, FoldersController], - providers: [AppService, ConfigService, CollectionCacheService], + controllers: [ + AppController, + ConfigController, + CollectionsController, + ResourcesController, + FoldersController, + LocalesController, + ], + providers: [AppService, ConfigService, CollectionCacheService, TranslationJobService, Logger], }) export class AppModule { constructor() { diff --git a/apps/api/src/app/collections/locales/locales.controller.spec.ts b/apps/api/src/app/collections/locales/locales.controller.spec.ts new file mode 100644 index 00000000..3200dbc3 --- /dev/null +++ b/apps/api/src/app/collections/locales/locales.controller.spec.ts @@ -0,0 +1,211 @@ +import { Test, type TestingModule } from '@nestjs/testing'; +import { HttpException, NotFoundException } from '@nestjs/common'; +import { LocalesController } from './locales.controller'; +import { ConfigService } from '../../config/config.service'; +import { CollectionCacheService } from '../../cache/collection-cache.service'; +import * as core from '@simoncodes-ca/core'; + +jest.mock('@simoncodes-ca/core', () => { + const actual = jest.requireActual('@simoncodes-ca/core'); + return { + ...actual, + addLocaleToCollection: jest.fn(), + removeLocaleFromCollection: jest.fn(), + }; +}); + +describe('LocalesController', () => { + let localesModule: TestingModule; + let localesController: LocalesController; + let cacheService: CollectionCacheService; + + const mockConfig = { + baseLocale: 'en', + locales: ['en', 'fr'], + collections: { + 'test-collection': { + translationsFolder: './translations/test', + baseLocale: 'en', + locales: ['en', 'fr'], + }, + }, + }; + + const mockCacheService = { + clearCache: jest.fn(), + }; + + beforeEach(async () => { + localesModule = await Test.createTestingModule({ + controllers: [LocalesController], + providers: [ + { + provide: ConfigService, + useValue: { + getConfig: jest.fn().mockReturnValue(mockConfig), + }, + }, + { + provide: CollectionCacheService, + useValue: mockCacheService, + }, + ], + }).compile(); + + localesController = localesModule.get(LocalesController); + cacheService = localesModule.get(CollectionCacheService); + + jest.clearAllMocks(); + }); + + describe('POST /locales (addLocale)', () => { + it('returns 200 with message, entriesBackfilled, and filesUpdated on success', async () => { + const mockResult = { + message: 'Locale "de" added to collection "test-collection" successfully', + entriesBackfilled: 4, + filesUpdated: 2, + }; + (core.addLocaleToCollection as jest.Mock).mockResolvedValue(mockResult); + + const result = await localesController.addLocale('test-collection', { locale: 'de' }); + + expect(core.addLocaleToCollection).toHaveBeenCalledWith('test-collection', 'de'); + expect(cacheService.clearCache).toHaveBeenCalled(); + expect(result).toEqual(mockResult); + }); + + it('returns 400 when locale already exists in collection', async () => { + (core.addLocaleToCollection as jest.Mock).mockRejectedValue( + new Error('Locale "fr" already exists in collection "test-collection"'), + ); + + await expect(localesController.addLocale('test-collection', { locale: 'fr' })).rejects.toThrow(HttpException); + + const error = await localesController + .addLocale('test-collection', { locale: 'fr' }) + .catch((e: HttpException) => e); + + expect((error as HttpException).getStatus()).toBe(400); + }); + + it('returns 404 when collection is not in config', async () => { + await expect(localesController.addLocale('nonexistent-collection', { locale: 'de' })).rejects.toThrow( + NotFoundException, + ); + }); + + it('returns 400 when trying to add the base locale', async () => { + (core.addLocaleToCollection as jest.Mock).mockRejectedValue( + new Error('Cannot add or remove the base locale "en"'), + ); + + const error = await localesController + .addLocale('test-collection', { locale: 'en' }) + .catch((e: HttpException) => e); + + expect((error as HttpException).getStatus()).toBe(400); + }); + + it('returns 400 when locale format is invalid', async () => { + (core.addLocaleToCollection as jest.Mock).mockRejectedValue(new Error('Invalid locale format: "not-valid-123"')); + + const error = await localesController + .addLocale('test-collection', { locale: 'not-valid-123' }) + .catch((e: HttpException) => e); + + expect((error as HttpException).getStatus()).toBe(400); + }); + + it('returns 500 for unexpected errors', async () => { + (core.addLocaleToCollection as jest.Mock).mockRejectedValue(new Error('Disk write failure')); + + const error = await localesController + .addLocale('test-collection', { locale: 'de' }) + .catch((e: HttpException) => e); + + expect((error as HttpException).getStatus()).toBe(500); + }); + + it('does not clear cache when collection lookup fails before core is called', async () => { + await localesController.addLocale('nonexistent-collection', { locale: 'de' }).catch(() => undefined); + + expect(cacheService.clearCache).not.toHaveBeenCalled(); + }); + }); + + describe('DELETE /locales/:locale (removeLocale)', () => { + it('returns 200 with message, entriesPurged, and filesUpdated on success', async () => { + const mockResult = { + message: 'Locale "fr" removed from collection "test-collection" successfully', + entriesPurged: 3, + filesUpdated: 2, + }; + (core.removeLocaleFromCollection as jest.Mock).mockResolvedValue(mockResult); + + const result = await localesController.removeLocale('test-collection', 'fr'); + + expect(core.removeLocaleFromCollection).toHaveBeenCalledWith('test-collection', 'fr'); + expect(cacheService.clearCache).toHaveBeenCalled(); + expect(result).toEqual(mockResult); + }); + + it('returns 404 when collection is not in config', async () => { + await expect(localesController.removeLocale('nonexistent-collection', 'fr')).rejects.toThrow(NotFoundException); + }); + + it('returns 400 when locale is not in the collection', async () => { + (core.removeLocaleFromCollection as jest.Mock).mockRejectedValue( + new Error('Locale "ja" not found in collection "test-collection"'), + ); + + const error = await localesController.removeLocale('test-collection', 'ja').catch((e: HttpException) => e); + + expect((error as HttpException).getStatus()).toBe(400); + }); + + it('returns 400 when trying to remove the base locale', async () => { + (core.removeLocaleFromCollection as jest.Mock).mockRejectedValue( + new Error('Cannot add or remove the base locale "en"'), + ); + + const error = await localesController.removeLocale('test-collection', 'en').catch((e: HttpException) => e); + + expect((error as HttpException).getStatus()).toBe(400); + }); + + it('returns 400 when locale format is invalid', async () => { + (core.removeLocaleFromCollection as jest.Mock).mockRejectedValue(new Error('Invalid locale format: "bad!"')); + + const error = await localesController.removeLocale('test-collection', 'bad!').catch((e: HttpException) => e); + + expect((error as HttpException).getStatus()).toBe(400); + }); + + it('returns 500 for unexpected errors', async () => { + (core.removeLocaleFromCollection as jest.Mock).mockRejectedValue(new Error('Disk write failure')); + + const error = await localesController.removeLocale('test-collection', 'fr').catch((e: HttpException) => e); + + expect((error as HttpException).getStatus()).toBe(500); + }); + + it('does not clear cache when collection lookup fails before core is called', async () => { + await localesController.removeLocale('nonexistent-collection', 'fr').catch(() => undefined); + + expect(cacheService.clearCache).not.toHaveBeenCalled(); + }); + + it('passes collection name and locale directly to core function', async () => { + const mockResult = { + message: 'Locale "fr" removed from collection "test-collection" successfully', + entriesPurged: 1, + filesUpdated: 1, + }; + (core.removeLocaleFromCollection as jest.Mock).mockResolvedValue(mockResult); + + await localesController.removeLocale('test-collection', 'fr'); + + expect(core.removeLocaleFromCollection).toHaveBeenCalledWith('test-collection', 'fr'); + }); + }); +}); diff --git a/apps/api/src/app/collections/locales/locales.controller.ts b/apps/api/src/app/collections/locales/locales.controller.ts new file mode 100644 index 00000000..4fa91beb --- /dev/null +++ b/apps/api/src/app/collections/locales/locales.controller.ts @@ -0,0 +1,96 @@ +import { Controller, Post, Delete, Param, Body, HttpException, HttpStatus, NotFoundException } from '@nestjs/common'; +import { addLocaleToCollection, removeLocaleFromCollection } from '@simoncodes-ca/core'; +import type { AddLocaleDto, AddLocaleResponseDto, RemoveLocaleResponseDto } from '@simoncodes-ca/data-transfer'; +import { ConfigService } from '../../config/config.service'; +import { CollectionCacheService } from '../../cache/collection-cache.service'; + +@Controller('collections/:collectionName/locales') +export class LocalesController { + readonly #configService: ConfigService; + readonly #cacheService: CollectionCacheService; + + constructor(configService: ConfigService, cacheService: CollectionCacheService) { + this.#configService = configService; + this.#cacheService = cacheService; + } + + @Post() + async addLocale( + @Param('collectionName') collectionName: string, + @Body() body: AddLocaleDto, + ): Promise { + try { + const config = this.#configService.getConfig(); + + if (!config.collections || !config.collections[collectionName]) { + throw new NotFoundException(`Collection "${collectionName}" not found`); + } + + const result = await addLocaleToCollection(collectionName, body.locale); + + this.#cacheService.clearCache(); + + return result; + } catch (error: unknown) { + if (error instanceof NotFoundException || error instanceof HttpException) { + throw error; + } + + const errorMessage = error instanceof Error ? error.message : 'Error adding locale'; + + if (errorMessage.includes('not found') || errorMessage.includes('not found in collection')) { + throw new NotFoundException(errorMessage); + } + + if ( + errorMessage.includes('already exists') || + errorMessage.includes('base locale') || + errorMessage.includes('Invalid locale') + ) { + throw new HttpException(errorMessage, HttpStatus.BAD_REQUEST); + } + + throw new HttpException(errorMessage, HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + @Delete(':locale') + async removeLocale( + @Param('collectionName') collectionName: string, + @Param('locale') locale: string, + ): Promise { + try { + const config = this.#configService.getConfig(); + + if (!config.collections || !config.collections[collectionName]) { + throw new NotFoundException(`Collection "${collectionName}" not found`); + } + + const result = await removeLocaleFromCollection(collectionName, locale); + + this.#cacheService.clearCache(); + + return result; + } catch (error: unknown) { + if (error instanceof NotFoundException || error instanceof HttpException) { + throw error; + } + + const errorMessage = error instanceof Error ? error.message : 'Error removing locale'; + + if (errorMessage.includes('Collection') && errorMessage.includes('not found')) { + throw new NotFoundException(errorMessage); + } + + if ( + errorMessage.includes('not found in collection') || + errorMessage.includes('base locale') || + errorMessage.includes('Invalid locale') + ) { + throw new HttpException(errorMessage, HttpStatus.BAD_REQUEST); + } + + throw new HttpException(errorMessage, HttpStatus.INTERNAL_SERVER_ERROR); + } + } +} diff --git a/apps/api/src/app/collections/resources/resources.controller.spec.ts b/apps/api/src/app/collections/resources/resources.controller.spec.ts index bddfb054..d2bd844b 100644 --- a/apps/api/src/app/collections/resources/resources.controller.spec.ts +++ b/apps/api/src/app/collections/resources/resources.controller.spec.ts @@ -6,6 +6,7 @@ import type { ResourceTreeDto } from '@simoncodes-ca/data-transfer'; import { ResourcesController } from './resources.controller'; import { ConfigService } from '../../config/config.service'; import { CollectionCacheService, CacheStatus } from '../../cache/collection-cache.service'; +import { TranslationJobService } from '../../translation-job/translation-job.service'; import * as core from '@simoncodes-ca/core'; // Mock the core module @@ -133,6 +134,13 @@ describe('ResourcesController', () => { provide: CollectionCacheService, useValue: mockCacheService, }, + { + provide: TranslationJobService, + useValue: { + startJob: jest.fn().mockReturnValue('mock-job-id'), + getJob: jest.fn().mockReturnValue(null), + }, + }, ], }).compile(); @@ -1509,4 +1517,149 @@ describe('ResourcesController', () => { expect(result.skippedLocales).toEqual(['fr-ca', 'es']); }); }); + + describe('translateLocale (POST translate-locale)', () => { + const configWithTranslation = { + ...mockConfig, + translation: { + enabled: true, + provider: 'google-translate', + apiKeyEnv: 'GOOGLE_TRANSLATE_API_KEY', + }, + }; + + const mockJobDto = { + jobId: 'mock-job-id', + collectionName: 'test-collection', + targetLocale: 'fr-ca', + status: 'pending' as const, + totalResources: 0, + translatedCount: 0, + failedCount: 0, + skippedCount: 0, + }; + + it('should return 202 with a job DTO when valid', async () => { + const translationJobService = resourcesModule.get(TranslationJobService); + (translationJobService.startJob as jest.Mock).mockReturnValue('mock-job-id'); + (translationJobService.getJob as jest.Mock).mockReturnValue(mockJobDto); + (configService.getConfig as jest.Mock).mockReturnValue(configWithTranslation); + + const mockResponse = { + status: jest.fn().mockReturnThis(), + json: jest.fn().mockReturnThis(), + }; + + await resourcesController.translateLocale('test-collection', { locale: 'fr-ca' }, mockResponse as any); + + expect(mockResponse.status).toHaveBeenCalledWith(202); + expect(mockResponse.json).toHaveBeenCalledWith(mockJobDto); + }); + + it('should return 404 when collection not found', async () => { + (configService.getConfig as jest.Mock).mockReturnValue({ ...mockConfig, collections: {} }); + + const mockResponse = { + status: jest.fn().mockReturnThis(), + json: jest.fn().mockReturnThis(), + }; + + await expect( + resourcesController.translateLocale('unknown-collection', { locale: 'fr-ca' }, mockResponse as any), + ).rejects.toThrow(NotFoundException); + }); + + it('should return 422 when translation is not enabled for the collection', async () => { + // mockConfig has no translation config — auto-translation is disabled by default + const mockResponse = { + status: jest.fn().mockReturnThis(), + json: jest.fn().mockReturnThis(), + }; + + try { + await resourcesController.translateLocale('test-collection', { locale: 'fr-ca' }, mockResponse as any); + fail('expected HttpException to be thrown'); + } catch (error: unknown) { + expect(error).toBeInstanceOf(HttpException); + expect((error as HttpException).getStatus()).toBe(422); + } + }); + + it('should return 400 when locale equals the base locale', async () => { + (configService.getConfig as jest.Mock).mockReturnValue(configWithTranslation); + + const mockResponse = { + status: jest.fn().mockReturnThis(), + json: jest.fn().mockReturnThis(), + }; + + try { + await resourcesController.translateLocale('test-collection', { locale: 'en' }, mockResponse as any); + fail('expected HttpException to be thrown'); + } catch (error: unknown) { + expect(error).toBeInstanceOf(HttpException); + expect((error as HttpException).getStatus()).toBe(400); + } + }); + + it('should return 400 when locale is not in the collection locales list', async () => { + (configService.getConfig as jest.Mock).mockReturnValue(configWithTranslation); + + const mockResponse = { + status: jest.fn().mockReturnThis(), + json: jest.fn().mockReturnThis(), + }; + + try { + await resourcesController.translateLocale('test-collection', { locale: 'de' }, mockResponse as any); + fail('expected HttpException to be thrown'); + } catch (error: unknown) { + expect(error).toBeInstanceOf(HttpException); + expect((error as HttpException).getStatus()).toBe(400); + } + }); + }); + + describe('getTranslateLocaleJob (GET translate-locale/:jobId)', () => { + const mockJobDto = { + jobId: 'known-job-id', + collectionName: 'test-collection', + targetLocale: 'fr-ca', + status: 'completed' as const, + totalResources: 10, + translatedCount: 9, + failedCount: 1, + skippedCount: 0, + }; + + it('should return the job DTO when found and collection matches', async () => { + const translationJobService = resourcesModule.get(TranslationJobService); + (translationJobService.getJob as jest.Mock).mockReturnValue(mockJobDto); + + const result = await resourcesController.getTranslateLocaleJob('test-collection', 'known-job-id'); + + expect(result).toEqual(mockJobDto); + }); + + it('should return 404 when job not found', async () => { + const translationJobService = resourcesModule.get(TranslationJobService); + (translationJobService.getJob as jest.Mock).mockReturnValue(undefined); + + await expect(resourcesController.getTranslateLocaleJob('test-collection', 'unknown-id')).rejects.toThrow( + NotFoundException, + ); + }); + + it('should return 404 when job exists but collectionName does not match', async () => { + const translationJobService = resourcesModule.get(TranslationJobService); + (translationJobService.getJob as jest.Mock).mockReturnValue({ + ...mockJobDto, + collectionName: 'other-collection', + }); + + await expect(resourcesController.getTranslateLocaleJob('test-collection', 'known-job-id')).rejects.toThrow( + NotFoundException, + ); + }); + }); }); diff --git a/apps/api/src/app/collections/resources/resources.controller.ts b/apps/api/src/app/collections/resources/resources.controller.ts index 50ba798d..64859baf 100644 --- a/apps/api/src/app/collections/resources/resources.controller.ts +++ b/apps/api/src/app/collections/resources/resources.controller.ts @@ -48,21 +48,32 @@ import type { TreeStatusResponseDto, TranslateResourceDto, TranslateResourceResponseDto, + TranslateLocaleRequestDto, + TranslateLocaleJobDto, } from '@simoncodes-ca/data-transfer'; import { ConfigService } from '../../config/config.service'; import { mapDtoToAddResourceParams } from '../../mappers/resource.mapper'; import { mapResourceTreeToDto, mapResourceEntryToSummary } from '../../mappers/resource-tree.mapper'; import { mapSearchResultsToDto } from '../../mappers/search-result.mapper'; import { CollectionCacheService, CacheStatus } from '../../cache/collection-cache.service'; +import { TranslationJobService } from '../../translation-job/translation-job.service'; @Controller('collections/:collectionName/resources') export class ResourcesController { readonly #logger = new Logger(ResourcesController.name); + readonly #configService: ConfigService; + readonly #cacheService: CollectionCacheService; + readonly #translationJobService: TranslationJobService; constructor( - private readonly configService: ConfigService, - private readonly cacheService: CollectionCacheService, - ) {} + configService: ConfigService, + cacheService: CollectionCacheService, + translationJobService: TranslationJobService, + ) { + this.#configService = configService; + this.#cacheService = cacheService; + this.#translationJobService = translationJobService; + } @Post('translate') async translateResource( @@ -71,7 +82,7 @@ export class ResourcesController { ): Promise { try { const decodedCollectionName = decodeURIComponent(collectionName); - const config = this.configService.getConfig(); + const config = this.#configService.getConfig(); if (!config.collections || !config.collections[decodedCollectionName]) { throw new NotFoundException(`Collection "${decodedCollectionName}" not found`); @@ -97,7 +108,7 @@ export class ResourcesController { cwd: process.cwd(), }); - this.cacheService.addResourceToCache( + this.#cacheService.addResourceToCache( decodedCollectionName, result.entry, dto.key.split('.').slice(0, -1).join('.'), @@ -136,7 +147,7 @@ export class ResourcesController { ): Promise { try { const decodedCollectionName = decodeURIComponent(collectionName); - const config = this.configService.getConfig(); + const config = this.#configService.getConfig(); if (!config.collections || !config.collections[decodedCollectionName]) { throw new NotFoundException(`Collection "${decodedCollectionName}" not found`); @@ -225,7 +236,7 @@ export class ResourcesController { ...(resource.tags && resource.tags.length > 0 && { tags: resource.tags }), }; - this.cacheService.addResourceToCache(decodedCollectionName, cacheEntry, folderPath); + this.#cacheService.addResourceToCache(decodedCollectionName, cacheEntry, folderPath); } catch (error: unknown) { // Validation errors (invalid key, etc.) should return 400 const errorMessage = error instanceof Error ? error.message : ''; @@ -266,7 +277,7 @@ export class ResourcesController { ): Promise { try { const decodedCollectionName = decodeURIComponent(collectionName); - const config = this.configService.getConfig(); + const config = this.#configService.getConfig(); if (!config.collections || !config.collections[decodedCollectionName]) { throw new NotFoundException(`Collection "${decodedCollectionName}" not found`); @@ -286,7 +297,7 @@ export class ResourcesController { // Clear cache after successful resource deletion if (result.entriesDeleted > 0) { - this.cacheService.clearCache(); + this.#cacheService.clearCache(); } return { @@ -314,7 +325,7 @@ export class ResourcesController { ): Promise { try { const decodedCollectionName = decodeURIComponent(collectionName); - const config = this.configService.getConfig(); + const config = this.#configService.getConfig(); if (!config.collections || !config.collections[decodedCollectionName]) { throw new NotFoundException(`Collection "${decodedCollectionName}" not found`); @@ -369,7 +380,7 @@ export class ResourcesController { // Clear cache after successful resource move if (result.movedCount > 0) { - this.cacheService.clearCache(); + this.#cacheService.clearCache(); } return result; @@ -390,7 +401,7 @@ export class ResourcesController { ): Promise { try { const decodedCollectionName = decodeURIComponent(collectionName); - const config = this.configService.getConfig(); + const config = this.#configService.getConfig(); if (!config.collections || !config.collections[decodedCollectionName]) { throw new NotFoundException(`Collection "${decodedCollectionName}" not found`); @@ -418,11 +429,11 @@ export class ResourcesController { if (dto.targetFolder !== undefined && dto.targetFolder !== oldFolderPath) { // Resource moved to a different folder — remove from old location, insert at new - this.cacheService.removeResourceFromCache(decodedCollectionName, entryKey, oldFolderPath); - this.cacheService.addResourceToCache(decodedCollectionName, result.entry, dto.targetFolder ?? ''); + this.#cacheService.removeResourceFromCache(decodedCollectionName, entryKey, oldFolderPath); + this.#cacheService.addResourceToCache(decodedCollectionName, result.entry, dto.targetFolder ?? ''); } else { // In-place edit — upsert in the same folder - this.cacheService.addResourceToCache(decodedCollectionName, result.entry, oldFolderPath); + this.#cacheService.addResourceToCache(decodedCollectionName, result.entry, oldFolderPath); } resourceDto = mapResourceEntryToSummary(result.entry); @@ -482,7 +493,7 @@ export class ResourcesController { isIncludeNested = false; } - const config = this.configService.getConfig(); + const config = this.#configService.getConfig(); if (!config.collections || !config.collections[decodedCollectionName]) { throw new NotFoundException(`Collection "${decodedCollectionName}" not found`); @@ -492,13 +503,13 @@ export class ResourcesController { const translationsFolder = collection.translationsFolder; // Check cache status - const cacheStatus = this.cacheService.getCacheStatus(decodedCollectionName); + const cacheStatus = this.#cacheService.getCacheStatus(decodedCollectionName); // Handle cache states if (cacheStatus === CacheStatus.NOT_STARTED || cacheStatus === CacheStatus.ERROR) { // Trigger indexing asynchronously (don't await) const locales = collection.locales ?? config.locales ?? []; - this.cacheService.indexCollection(decodedCollectionName, translationsFolder, locales.length).catch((error) => { + this.#cacheService.indexCollection(decodedCollectionName, translationsFolder, locales.length).catch((error) => { this.#logger.warn(`Async indexing failed for ${decodedCollectionName}`, error); }); @@ -531,7 +542,7 @@ export class ResourcesController { } // Cache is READY - retrieve cached tree - const cachedTree = this.cacheService.getCache(decodedCollectionName); + const cachedTree = this.#cacheService.getCache(decodedCollectionName); if (!cachedTree) { throw new HttpException('Cache is marked as ready but tree is not available', HttpStatus.INTERNAL_SERVER_ERROR); @@ -611,13 +622,13 @@ export class ResourcesController { async getCacheStatus(@Param('collectionName') collectionName: string): Promise { try { const decodedCollectionName = decodeURIComponent(collectionName); - const config = this.configService.getConfig(); + const config = this.#configService.getConfig(); if (!config.collections || !config.collections[decodedCollectionName]) { throw new NotFoundException(`Collection "${decodedCollectionName}" not found`); } - const cacheStatus = this.cacheService.getCacheStatus(decodedCollectionName); + const cacheStatus = this.#cacheService.getCacheStatus(decodedCollectionName); // If cache is not started, trigger indexing asynchronously const collection = config.collections[decodedCollectionName]; @@ -625,13 +636,13 @@ export class ResourcesController { const translationsFolder = collection.translationsFolder; const locales = collection.locales ?? config.locales ?? []; - this.cacheService.indexCollection(decodedCollectionName, translationsFolder, locales.length).catch((error) => { + this.#cacheService.indexCollection(decodedCollectionName, translationsFolder, locales.length).catch((error) => { this.#logger.warn(`Async indexing failed for ${decodedCollectionName}`, error); }); } // Get additional cache metadata - const metadata = this.cacheService.getCacheMetadata(decodedCollectionName); + const metadata = this.#cacheService.getCacheMetadata(decodedCollectionName); // Map CacheStatus enum to CacheStatusType string literal const statusType = cacheStatus as 'not-started' | 'indexing' | 'ready' | 'error'; @@ -651,7 +662,7 @@ export class ResourcesController { // Include stats when cache is ready if (cacheStatus === CacheStatus.READY) { - const stats = this.cacheService.getCacheStats(decodedCollectionName); + const stats = this.#cacheService.getCacheStats(decodedCollectionName); if (stats) { statusDto.stats = stats; } @@ -679,7 +690,7 @@ export class ResourcesController { ): Promise { try { const decodedCollectionName = decodeURIComponent(collectionName); - const config = this.configService.getConfig(); + const config = this.#configService.getConfig(); if (!config.collections || !config.collections[decodedCollectionName]) { throw new NotFoundException(`Collection "${decodedCollectionName}" not found`); @@ -703,7 +714,7 @@ export class ResourcesController { const maxResults = Math.min(dto.maxResults || 100, 500); // Try to use cached tree for faster search - const cachedTree = this.cacheService.getCache(decodedCollectionName); + const cachedTree = this.#cacheService.getCache(decodedCollectionName); let searchResults: SearchResult[]; if (cachedTree) { @@ -748,4 +759,67 @@ export class ResourcesController { throw new HttpException(errorMessage, HttpStatus.INTERNAL_SERVER_ERROR); } } + + @Post('translate-locale') + async translateLocale( + @Param('collectionName') collectionName: string, + @Body() dto: TranslateLocaleRequestDto, + @Res() response: Response, + ): Promise { + const decodedCollectionName = decodeURIComponent(collectionName); + const config = this.#configService.getConfig(); + + if (!config.collections || !config.collections[decodedCollectionName]) { + throw new NotFoundException(`Collection "${decodedCollectionName}" not found`); + } + + const collection = config.collections[decodedCollectionName]; + const translationConfig = collection.translation ?? config.translation; + + if (!translationConfig?.enabled) { + throw new HttpException('Auto-translation is not enabled for this collection', HttpStatus.UNPROCESSABLE_ENTITY); + } + + const baseLocale = collection.baseLocale || config.baseLocale || 'en'; + const allLocales = collection.locales ?? config.locales ?? []; + + if (dto.locale === baseLocale || !allLocales.includes(dto.locale)) { + throw new HttpException( + `Invalid locale "${dto.locale}": must be a non-base locale defined in the collection's locales`, + HttpStatus.BAD_REQUEST, + ); + } + + const jobId = this.#translationJobService.startJob({ + collectionName: decodedCollectionName, + translationsFolder: collection.translationsFolder, + translationConfig, + targetLocale: dto.locale, + baseLocale, + allLocales, + cwd: process.cwd(), + }); + + const job = this.#translationJobService.getJob(jobId); + (response as unknown as import('express').Response).status(HttpStatus.ACCEPTED).json(job); + } + + @Get('translate-locale/:jobId') + async getTranslateLocaleJob( + @Param('collectionName') collectionName: string, + @Param('jobId') jobId: string, + ): Promise { + const decodedCollectionName = decodeURIComponent(collectionName); + const job = this.#translationJobService.getJob(jobId); + + if (job === undefined) { + throw new NotFoundException(`Translation job "${jobId}" not found`); + } + + if (job.collectionName !== decodedCollectionName) { + throw new NotFoundException(`Translation job "${jobId}" not found`); + } + + return job; + } } diff --git a/apps/api/src/app/translation-job/translation-job.service.spec.ts b/apps/api/src/app/translation-job/translation-job.service.spec.ts new file mode 100644 index 00000000..864d9987 --- /dev/null +++ b/apps/api/src/app/translation-job/translation-job.service.spec.ts @@ -0,0 +1,170 @@ +import { Logger } from '@nestjs/common'; +import { TranslationJobService } from './translation-job.service'; +import { TranslationError } from '@simoncodes-ca/core'; +import type { TranslateLocaleResult, TranslateLocaleProgress } from '@simoncodes-ca/core'; + +const mockTranslateLocale = jest.fn(); + +jest.mock('@simoncodes-ca/core', () => { + const actual = jest.requireActual('@simoncodes-ca/core'); + return { + ...actual, + translateLocale: (params: unknown) => mockTranslateLocale(params), + }; +}); + +const makeSuccessResult = (overrides: Partial = {}): TranslateLocaleResult => ({ + totalResources: 10, + translatedCount: 9, + failedCount: 1, + skippedCount: 0, + failures: [{ key: 'apps.button.ok', error: 'Rate limit exceeded' }], + skippedKeys: [], + ...overrides, +}); + +const makeStartJobParams = () => ({ + collectionName: 'my-collection', + translationsFolder: '/path/to/translations', + translationConfig: { enabled: true, provider: 'google', apiKeyEnv: 'GOOGLE_API_KEY' }, + targetLocale: 'fr', + baseLocale: 'en', + allLocales: ['en', 'fr', 'de'], + cwd: '/workspace', +}); + +describe('TranslationJobService', () => { + let service: TranslationJobService; + let mockLogger: jest.Mocked>; + + beforeEach(() => { + jest.clearAllMocks(); + mockLogger = { error: jest.fn(), log: jest.fn(), warn: jest.fn() }; + service = new TranslationJobService(mockLogger as unknown as Logger); + }); + + it('startJob returns a non-empty job ID', () => { + mockTranslateLocale.mockReturnValue(new Promise(() => {})); // never resolves + + const jobId = service.startJob(makeStartJobParams()); + + expect(jobId).toBeTruthy(); + expect(typeof jobId).toBe('string'); + }); + + it('getJob returns undefined for an unknown job ID', () => { + const result = service.getJob('non-existent-id'); + + expect(result).toBeUndefined(); + }); + + it('getJob returns a running job immediately after startJob (before async completes)', () => { + mockTranslateLocale.mockReturnValue(new Promise(() => {})); // never resolves + + const jobId = service.startJob(makeStartJobParams()); + const job = service.getJob(jobId); + + expect(job).toBeDefined(); + expect(job?.jobId).toBe(jobId); + expect(job?.collectionName).toBe('my-collection'); + expect(job?.targetLocale).toBe('fr'); + expect(['pending', 'running']).toContain(job?.status); + }); + + it('job status becomes completed with correct counts after async resolves', async () => { + const result = makeSuccessResult(); + mockTranslateLocale.mockResolvedValue(result); + + const jobId = service.startJob(makeStartJobParams()); + + // Wait for the microtask queue to flush the resolved promise + await Promise.resolve(); + await Promise.resolve(); + + const job = service.getJob(jobId); + expect(job).toBeDefined(); + expect(job?.status).toBe('completed'); + expect(job?.totalResources).toBe(result.totalResources); + expect(job?.translatedCount).toBe(result.translatedCount); + expect(job?.failedCount).toBe(result.failedCount); + expect(job?.skippedCount).toBe(result.skippedCount); + expect(job?.failures).toEqual(result.failures); + expect(job?.completedAt).toBeDefined(); + }); + + it('job status becomes failed when translateLocale throws a TranslationError', async () => { + mockTranslateLocale.mockRejectedValue(new TranslationError('API quota exceeded', 'QUOTA_EXCEEDED', false)); + + const jobId = service.startJob(makeStartJobParams()); + + await Promise.resolve(); + await Promise.resolve(); + + const job = service.getJob(jobId); + expect(job).toBeDefined(); + expect(job?.status).toBe('failed'); + expect(job?.completedAt).toBeDefined(); + }); + + it('job status becomes failed when translateLocale throws a generic Error', async () => { + mockTranslateLocale.mockRejectedValue(new Error('Unexpected network failure')); + + const jobId = service.startJob(makeStartJobParams()); + + await Promise.resolve(); + await Promise.resolve(); + + const job = service.getJob(jobId); + expect(job).toBeDefined(); + expect(job?.status).toBe('failed'); + }); + + it('getJob omits optional fields when there are no failures or skipped keys', async () => { + mockTranslateLocale.mockResolvedValue(makeSuccessResult({ failures: [], skippedKeys: [] })); + + const jobId = service.startJob(makeStartJobParams()); + + await Promise.resolve(); + await Promise.resolve(); + + const job = service.getJob(jobId); + expect(job).toBeDefined(); + expect(job?.failures).toBeUndefined(); + expect(job?.skippedKeys).toBeUndefined(); + }); + + it('updates job counts when onProgress is called', async () => { + let resolveTranslation!: (result: TranslateLocaleResult) => void; + + mockTranslateLocale.mockImplementationOnce( + (params: { onProgress?: (p: TranslateLocaleProgress) => void }) => + new Promise((resolve) => { + resolveTranslation = resolve; + params.onProgress?.({ + totalResources: 10, + translatedCount: 3, + failedCount: 0, + skippedCount: 1, + currentBatch: 1, + totalBatches: 2, + }); + }), + ); + + const jobId = service.startJob(makeStartJobParams()); + + // Give the microtask queue a tick so the async function runs up to its first await + // (the Promise constructor callback runs synchronously, so onProgress has already been called) + await new Promise((resolve) => setImmediate(resolve)); + + // The promise has NOT resolved yet — the progress counts should reflect the onProgress call + const jobDuringProgress = service.getJob(jobId); + expect(jobDuringProgress?.translatedCount).toBe(3); + expect(jobDuringProgress?.totalResources).toBe(10); + + // Clean up by resolving the translation so no unhandled promise dangles + resolveTranslation(makeSuccessResult({ totalResources: 10, translatedCount: 10, failedCount: 0, skippedCount: 0 })); + await Promise.resolve(); + await Promise.resolve(); + }); +}); diff --git a/apps/api/src/app/translation-job/translation-job.service.ts b/apps/api/src/app/translation-job/translation-job.service.ts new file mode 100644 index 00000000..a30fcf90 --- /dev/null +++ b/apps/api/src/app/translation-job/translation-job.service.ts @@ -0,0 +1,144 @@ +import { Injectable, Logger } from '@nestjs/common'; +import { randomUUID } from 'node:crypto'; +import { translateLocale, TranslationError } from '@simoncodes-ca/core'; +import type { TranslateLocaleParams, TranslateLocaleProgress } from '@simoncodes-ca/core'; +import type { TranslateLocaleJobDto } from '@simoncodes-ca/data-transfer'; + +interface TranslationJob { + jobId: string; + collectionName: string; + targetLocale: string; + status: 'pending' | 'running' | 'completed' | 'failed'; + totalResources: number; + translatedCount: number; + failedCount: number; + skippedCount: number; + failures: Array<{ key: string; error: string }>; + skippedKeys: string[]; + startedAt?: Date; + completedAt?: Date; + error?: string; +} + +@Injectable() +export class TranslationJobService { + readonly #logger: Logger; + readonly #jobs = new Map(); + + constructor(logger: Logger) { + this.#logger = logger; + } + + /** + * Kicks off an async translate-locale job and returns its ID immediately. + * The caller can poll `getJob(jobId)` to track progress. + */ + startJob(params: TranslateLocaleParams & { collectionName: string }): string { + const jobId = randomUUID(); + + const job: TranslationJob = { + jobId, + collectionName: params.collectionName, + targetLocale: params.targetLocale, + status: 'pending', + totalResources: 0, + translatedCount: 0, + failedCount: 0, + skippedCount: 0, + failures: [], + skippedKeys: [], + }; + + this.#jobs.set(jobId, job); + + this.#runJob(jobId, params); + + return jobId; + } + + /** Returns the current snapshot of a job as a DTO, or undefined if the job ID is unknown. */ + getJob(jobId: string): TranslateLocaleJobDto | undefined { + const job = this.#jobs.get(jobId); + + if (!job) { + return undefined; + } + + return this.#toDto(job); + } + + #runJob(jobId: string, params: TranslateLocaleParams & { collectionName: string }): void { + const { collectionName: _collectionName, ...translateParams } = params; + + const onProgress = (progress: TranslateLocaleProgress): void => { + const job = this.#jobs.get(jobId); + + if (!job) { + return; + } + + job.totalResources = progress.totalResources; + job.translatedCount = progress.translatedCount; + job.failedCount = progress.failedCount; + job.skippedCount = progress.skippedCount; + }; + + const runningJob = this.#jobs.get(jobId); + if (!runningJob) return; + runningJob.status = 'running'; + runningJob.startedAt = new Date(); + + translateLocale({ ...translateParams, onProgress }) + .then((result) => { + const completedJob = this.#jobs.get(jobId); + + if (!completedJob) { + return; + } + + completedJob.status = 'completed'; + completedJob.completedAt = new Date(); + completedJob.totalResources = result.totalResources; + completedJob.translatedCount = result.translatedCount; + completedJob.failedCount = result.failedCount; + completedJob.skippedCount = result.skippedCount; + completedJob.failures = [...result.failures]; + completedJob.skippedKeys = [...result.skippedKeys]; + }) + .catch((error: unknown) => { + const failedJob = this.#jobs.get(jobId); + + if (!failedJob) { + return; + } + + failedJob.status = 'failed'; + failedJob.completedAt = new Date(); + + if (error instanceof TranslationError || error instanceof Error) { + failedJob.error = error.message; + } else { + failedJob.error = 'An unexpected error occurred'; + } + + this.#logger.error(`Translation job ${jobId} failed: ${failedJob.error}`); + }); + } + + #toDto(job: TranslationJob): TranslateLocaleJobDto { + return { + jobId: job.jobId, + collectionName: job.collectionName, + targetLocale: job.targetLocale, + status: job.status, + totalResources: job.totalResources, + translatedCount: job.translatedCount, + failedCount: job.failedCount, + skippedCount: job.skippedCount, + ...(job.failures.length > 0 && { failures: job.failures }), + ...(job.skippedKeys.length > 0 && { skippedKeys: job.skippedKeys }), + ...(job.startedAt && { startedAt: job.startedAt.toISOString() }), + ...(job.completedAt && { completedAt: job.completedAt.toISOString() }), + }; + } +} diff --git a/apps/cli/src/commands/add-locale.spec.ts b/apps/cli/src/commands/add-locale.spec.ts new file mode 100644 index 00000000..a9d3993f --- /dev/null +++ b/apps/cli/src/commands/add-locale.spec.ts @@ -0,0 +1,123 @@ +import { describe, it, expect, beforeEach, vi } from 'vitest'; +import { addLocaleCommand, type AddLocaleOptions } from './add-locale'; + +vi.mock('@simoncodes-ca/core', () => ({ + addLocaleToCollection: vi.fn(), +})); + +vi.mock('../utils', () => ({ + loadConfiguration: vi.fn(), + promptForCollection: vi.fn(), + resolveCollection: vi.fn(), + ConsoleFormatter: { + error: vi.fn(), + success: vi.fn(), + keyValue: vi.fn(), + }, +})); + +vi.mock('prompts', () => ({ + default: vi.fn(), +})); + +import { addLocaleToCollection } from '@simoncodes-ca/core'; +import { loadConfiguration, promptForCollection, resolveCollection, ConsoleFormatter } from '../utils'; + +const BASE_CONFIG = { + baseLocale: 'en', + locales: ['en', 'fr'], + collections: { + main: { translationsFolder: 'src/i18n' }, + }, +}; + +const LOADED_CONFIG = { + config: BASE_CONFIG, + configPath: '/project/.lingo-tracker.json', + cwd: '/project', +}; + +const RESOLVED_COLLECTION = { + name: 'main', + config: { translationsFolder: 'src/i18n' }, + translationsFolderPath: '/project/src/i18n', +}; + +describe('addLocaleCommand', () => { + beforeEach(() => { + vi.clearAllMocks(); + vi.mocked(loadConfiguration).mockReturnValue(LOADED_CONFIG); + vi.mocked(promptForCollection).mockResolvedValue('main'); + vi.mocked(resolveCollection).mockReturnValue(RESOLVED_COLLECTION); + }); + + it('returns early when loadConfiguration returns null', async () => { + vi.mocked(loadConfiguration).mockReturnValue(null); + + await addLocaleCommand({ locale: 'de' }); + + expect(addLocaleToCollection).not.toHaveBeenCalled(); + }); + + it('returns early when promptForCollection returns null', async () => { + vi.mocked(promptForCollection).mockResolvedValue(null); + + await addLocaleCommand({ locale: 'de' }); + + expect(addLocaleToCollection).not.toHaveBeenCalled(); + }); + + it('returns early when resolveCollection returns null', async () => { + vi.mocked(resolveCollection).mockReturnValue(null); + + await addLocaleCommand({ locale: 'de' }); + + expect(addLocaleToCollection).not.toHaveBeenCalled(); + }); + + describe('non-TTY mode', () => { + beforeEach(() => { + Object.defineProperty(process.stdout, 'isTTY', { value: false, configurable: true }); + }); + + it('calls addLocaleToCollection and prints success when --locale is provided', async () => { + vi.mocked(addLocaleToCollection).mockResolvedValue({ + message: 'Locale "de" added to collection "main" successfully', + entriesBackfilled: 3, + filesUpdated: 2, + }); + + const options: AddLocaleOptions = { collection: 'main', locale: 'de' }; + await addLocaleCommand(options); + + expect(addLocaleToCollection).toHaveBeenCalledWith('main', 'de', { cwd: '/project' }); + expect(ConsoleFormatter.success).toHaveBeenCalledWith('Locale "de" added to collection "main" successfully'); + expect(ConsoleFormatter.keyValue).toHaveBeenCalledWith('Entries backfilled', 3); + expect(ConsoleFormatter.keyValue).toHaveBeenCalledWith('Files updated', 2); + }); + + it('prints error and returns without calling core when --locale is missing', async () => { + const options: AddLocaleOptions = { collection: 'main' }; + await addLocaleCommand(options); + + expect(ConsoleFormatter.error).toHaveBeenCalledWith('Missing required option: --locale'); + expect(addLocaleToCollection).not.toHaveBeenCalled(); + }); + + it('prints error via ConsoleFormatter.error when core function throws', async () => { + vi.mocked(addLocaleToCollection).mockRejectedValue(new Error('Locale "de" already exists in collection "main"')); + + await addLocaleCommand({ collection: 'main', locale: 'de' }); + + expect(ConsoleFormatter.error).toHaveBeenCalledWith('Locale "de" already exists in collection "main"'); + }); + + it('prints generic error message when core throws a non-Error value', async () => { + vi.mocked(addLocaleToCollection).mockRejectedValue('unexpected'); + + await addLocaleCommand({ collection: 'main', locale: 'de' }); + + expect(ConsoleFormatter.error).toHaveBeenCalledWith('Failed to add locale'); + }); + }); +}); diff --git a/apps/cli/src/commands/add-locale.ts b/apps/cli/src/commands/add-locale.ts new file mode 100644 index 00000000..a0f18aaf --- /dev/null +++ b/apps/cli/src/commands/add-locale.ts @@ -0,0 +1,51 @@ +import prompts from 'prompts'; +import { addLocaleToCollection } from '@simoncodes-ca/core'; +import { loadConfiguration, promptForCollection, resolveCollection, ConsoleFormatter } from '../utils'; + +export interface AddLocaleOptions { + collection?: string; + locale?: string; +} + +export async function addLocaleCommand(options: AddLocaleOptions): Promise { + const loaded = loadConfiguration({ exitOnError: false }); + if (!loaded) return; + const { config, cwd } = loaded; + + const collectionName = await promptForCollection(config, options.collection); + if (!collectionName) return; + + const collection = resolveCollection(collectionName, config, cwd); + if (!collection) return; + + let locale = options.locale; + + if (!locale) { + if (!process.stdout.isTTY) { + ConsoleFormatter.error('Missing required option: --locale'); + return; + } + + const answer = await prompts( + { + type: 'text', + name: 'locale', + message: 'Enter locale to add (e.g. fr-ca, de, es)', + }, + { onCancel: () => process.exit(0) }, + ); + + locale = answer.locale as string; + } + + if (!locale) return; + + try { + const result = await addLocaleToCollection(collectionName, locale, { cwd }); + ConsoleFormatter.success(result.message); + ConsoleFormatter.keyValue('Entries backfilled', result.entriesBackfilled); + ConsoleFormatter.keyValue('Files updated', result.filesUpdated); + } catch (e: unknown) { + ConsoleFormatter.error(e instanceof Error ? e.message : 'Failed to add locale'); + } +} diff --git a/apps/cli/src/commands/export-cmd.ts b/apps/cli/src/commands/export-cmd.ts index d85ec51f..08a50b96 100644 --- a/apps/cli/src/commands/export-cmd.ts +++ b/apps/cli/src/commands/export-cmd.ts @@ -477,7 +477,7 @@ async function promptForMissing( questions.push({ type: 'text', name: 'filename', - message: 'Custom filename pattern (optional, e.g., "translations-{locale}.{ext}")', + message: 'Custom filename pattern (optional, e.g., "translations-{locale}")', initial: '', }); } diff --git a/apps/cli/src/commands/remove-locale.spec.ts b/apps/cli/src/commands/remove-locale.spec.ts new file mode 100644 index 00000000..be9e5a0b --- /dev/null +++ b/apps/cli/src/commands/remove-locale.spec.ts @@ -0,0 +1,123 @@ +import { describe, it, expect, beforeEach, vi } from 'vitest'; +import { removeLocaleCommand, type RemoveLocaleOptions } from './remove-locale'; + +vi.mock('@simoncodes-ca/core', () => ({ + removeLocaleFromCollection: vi.fn(), +})); + +vi.mock('../utils', () => ({ + loadConfiguration: vi.fn(), + promptForCollection: vi.fn(), + resolveCollection: vi.fn(), + ConsoleFormatter: { + error: vi.fn(), + success: vi.fn(), + keyValue: vi.fn(), + }, +})); + +vi.mock('prompts', () => ({ + default: vi.fn(), +})); + +import { removeLocaleFromCollection } from '@simoncodes-ca/core'; +import { loadConfiguration, promptForCollection, resolveCollection, ConsoleFormatter } from '../utils'; + +const BASE_CONFIG = { + baseLocale: 'en', + locales: ['en', 'fr', 'de'], + collections: { + main: { translationsFolder: 'src/i18n' }, + }, +}; + +const LOADED_CONFIG = { + config: BASE_CONFIG, + configPath: '/project/.lingo-tracker.json', + cwd: '/project', +}; + +const RESOLVED_COLLECTION = { + name: 'main', + config: { translationsFolder: 'src/i18n', locales: ['en', 'fr', 'de'] }, + translationsFolderPath: '/project/src/i18n', +}; + +describe('removeLocaleCommand', () => { + beforeEach(() => { + vi.clearAllMocks(); + vi.mocked(loadConfiguration).mockReturnValue(LOADED_CONFIG); + vi.mocked(promptForCollection).mockResolvedValue('main'); + vi.mocked(resolveCollection).mockReturnValue(RESOLVED_COLLECTION); + }); + + it('returns early when loadConfiguration returns null', async () => { + vi.mocked(loadConfiguration).mockReturnValue(null); + + await removeLocaleCommand({ locale: 'fr' }); + + expect(removeLocaleFromCollection).not.toHaveBeenCalled(); + }); + + it('returns early when promptForCollection returns null', async () => { + vi.mocked(promptForCollection).mockResolvedValue(null); + + await removeLocaleCommand({ locale: 'fr' }); + + expect(removeLocaleFromCollection).not.toHaveBeenCalled(); + }); + + it('returns early when resolveCollection returns null', async () => { + vi.mocked(resolveCollection).mockReturnValue(null); + + await removeLocaleCommand({ locale: 'fr' }); + + expect(removeLocaleFromCollection).not.toHaveBeenCalled(); + }); + + describe('non-TTY mode', () => { + beforeEach(() => { + Object.defineProperty(process.stdout, 'isTTY', { value: false, configurable: true }); + }); + + it('calls removeLocaleFromCollection and prints success when --locale is provided', async () => { + vi.mocked(removeLocaleFromCollection).mockResolvedValue({ + message: 'Locale "fr" removed from collection "main" successfully', + entriesPurged: 5, + filesUpdated: 3, + }); + + const options: RemoveLocaleOptions = { collection: 'main', locale: 'fr' }; + await removeLocaleCommand(options); + + expect(removeLocaleFromCollection).toHaveBeenCalledWith('main', 'fr', { cwd: '/project' }); + expect(ConsoleFormatter.success).toHaveBeenCalledWith('Locale "fr" removed from collection "main" successfully'); + expect(ConsoleFormatter.keyValue).toHaveBeenCalledWith('Entries purged', 5); + expect(ConsoleFormatter.keyValue).toHaveBeenCalledWith('Files updated', 3); + }); + + it('prints error and returns without calling core when --locale is missing', async () => { + const options: RemoveLocaleOptions = { collection: 'main' }; + await removeLocaleCommand(options); + + expect(ConsoleFormatter.error).toHaveBeenCalledWith('Missing required option: --locale'); + expect(removeLocaleFromCollection).not.toHaveBeenCalled(); + }); + + it('prints error via ConsoleFormatter.error when core function throws', async () => { + vi.mocked(removeLocaleFromCollection).mockRejectedValue(new Error('Locale "fr" not found in collection "main"')); + + await removeLocaleCommand({ collection: 'main', locale: 'fr' }); + + expect(ConsoleFormatter.error).toHaveBeenCalledWith('Locale "fr" not found in collection "main"'); + }); + + it('prints generic error message when core throws a non-Error value', async () => { + vi.mocked(removeLocaleFromCollection).mockRejectedValue('unexpected'); + + await removeLocaleCommand({ collection: 'main', locale: 'fr' }); + + expect(ConsoleFormatter.error).toHaveBeenCalledWith('Failed to remove locale'); + }); + }); +}); diff --git a/apps/cli/src/commands/remove-locale.ts b/apps/cli/src/commands/remove-locale.ts new file mode 100644 index 00000000..972abb9d --- /dev/null +++ b/apps/cli/src/commands/remove-locale.ts @@ -0,0 +1,62 @@ +import prompts from 'prompts'; +import { removeLocaleFromCollection } from '@simoncodes-ca/core'; +import { loadConfiguration, promptForCollection, resolveCollection, ConsoleFormatter } from '../utils'; + +export interface RemoveLocaleOptions { + collection?: string; + locale?: string; +} + +export async function removeLocaleCommand(options: RemoveLocaleOptions): Promise { + const loaded = loadConfiguration({ exitOnError: false }); + if (!loaded) return; + const { config, cwd } = loaded; + + const collectionName = await promptForCollection(config, options.collection); + if (!collectionName) return; + + const collection = resolveCollection(collectionName, config, cwd); + if (!collection) return; + + const baseLocale = collection.config.baseLocale ?? config.baseLocale; + const effectiveLocales = (collection.config.locales ?? config.locales ?? []).filter( + (l) => baseLocale === undefined || l !== baseLocale, + ); + + let locale = options.locale; + + if (!locale) { + if (!process.stdout.isTTY) { + ConsoleFormatter.error('Missing required option: --locale'); + return; + } + + if (effectiveLocales.length === 0) { + ConsoleFormatter.error(`No removable locales in collection "${collectionName}".`); + return; + } + + const answer = await prompts( + { + type: 'select', + name: 'locale', + message: 'Select locale to remove', + choices: effectiveLocales.map((l) => ({ title: l, value: l })), + }, + { onCancel: () => process.exit(0) }, + ); + + locale = answer.locale as string; + } + + if (!locale) return; + + try { + const result = await removeLocaleFromCollection(collectionName, locale, { cwd }); + ConsoleFormatter.success(result.message); + ConsoleFormatter.keyValue('Entries purged', result.entriesPurged); + ConsoleFormatter.keyValue('Files updated', result.filesUpdated); + } catch (e: unknown) { + ConsoleFormatter.error(e instanceof Error ? e.message : 'Failed to remove locale'); + } +} diff --git a/apps/cli/src/commands/translate-locale.ts b/apps/cli/src/commands/translate-locale.ts new file mode 100644 index 00000000..6b749bd7 --- /dev/null +++ b/apps/cli/src/commands/translate-locale.ts @@ -0,0 +1,179 @@ +import prompts from 'prompts'; +import { translateLocale } from '@simoncodes-ca/core'; +import { loadConfiguration, resolveCollection, ConsoleFormatter, ErrorMessages } from '../utils'; + +export interface TranslateLocaleOptions { + collection?: string; + locale?: string; + verbose?: boolean; +} + +/** + * CLI command that auto-translates all `new` and `stale` resources for a + * single target locale within a collection. + * + * In TTY mode, missing `collection` and `locale` options trigger interactive + * prompts. In non-TTY mode both flags are required. + */ +export async function translateLocaleCommand(options: TranslateLocaleOptions): Promise { + const loaded = loadConfiguration({ exitOnError: false }); + if (!loaded) return; + const { config, cwd } = loaded; + + // ------------------------------------------------------------------------- + // Resolve collection + // ------------------------------------------------------------------------- + + let collectionName = options.collection; + + if (!collectionName) { + const collectionNames = Object.keys(config.collections ?? {}); + + if (collectionNames.length === 0) { + ConsoleFormatter.error(ErrorMessages.NO_COLLECTIONS); + return; + } + + if (!process.stdout.isTTY) { + ConsoleFormatter.error(ErrorMessages.MISSING_OPTION('collection')); + return; + } + + const answer = await prompts( + { + type: 'select', + name: 'collection', + message: 'Select collection to translate', + choices: collectionNames.map((name) => ({ title: name, value: name })), + }, + { onCancel: () => process.exit(0) }, + ); + + collectionName = answer.collection as string; + } + + const collection = resolveCollection(collectionName, config, cwd); + if (!collection) return; + + // ------------------------------------------------------------------------- + // Validate translation is enabled + // ------------------------------------------------------------------------- + + const translationEnabled = collection.config.translation?.enabled ?? config.translation?.enabled ?? false; + if (!translationEnabled) { + ConsoleFormatter.error( + `Auto-translation is not enabled for collection "${collectionName}". ` + + `Set translation.enabled = true in your configuration.`, + ); + return; + } + + const baseLocale = collection.config.baseLocale ?? config.baseLocale ?? 'en'; + const allLocales = collection.config.locales ?? config.locales ?? []; + + const nonBaseLocales = allLocales.filter((locale) => locale !== baseLocale); + + if (nonBaseLocales.length === 0) { + ConsoleFormatter.error(`No target locales configured. Add locales other than the base locale "${baseLocale}".`); + return; + } + + // ------------------------------------------------------------------------- + // Resolve target locale + // ------------------------------------------------------------------------- + + let targetLocale = options.locale; + + if (!targetLocale) { + if (!process.stdout.isTTY) { + ConsoleFormatter.error(ErrorMessages.MISSING_OPTION('locale')); + return; + } + + const answer = await prompts( + { + type: 'select', + name: 'locale', + message: 'Select target locale to translate', + choices: nonBaseLocales.map((locale) => ({ title: locale, value: locale })), + }, + { onCancel: () => process.exit(0) }, + ); + + targetLocale = answer.locale as string; + } + + if (targetLocale === baseLocale) { + ConsoleFormatter.error(`Cannot translate to the base locale "${baseLocale}".`); + return; + } + + if (!allLocales.includes(targetLocale)) { + ConsoleFormatter.error(`Locale "${targetLocale}" is not configured. Available locales: ${allLocales.join(', ')}`); + return; + } + + // ------------------------------------------------------------------------- + // Resolve translation config + // ------------------------------------------------------------------------- + + const translationConfig = collection.config.translation ?? config.translation; + if (!translationConfig) { + ConsoleFormatter.error('Translation configuration is missing. Check your .lingo-tracker.json.'); + return; + } + + // ------------------------------------------------------------------------- + // Run translation + // ------------------------------------------------------------------------- + + const translationsFolder = collection.config.translationsFolder; + + console.log(''); + ConsoleFormatter.progress(`Translating locale '${targetLocale}' in collection '${collectionName}'...`); + + try { + const result = await translateLocale({ + translationsFolder, + translationConfig, + targetLocale, + baseLocale, + allLocales, + cwd, + onProgress: options.verbose + ? (progress) => { + ConsoleFormatter.indent( + `[batch ${progress.currentBatch}/${progress.totalBatches}] ` + + `translated: ${progress.translatedCount}, skipped: ${progress.skippedCount}, failed: ${progress.failedCount}`, + ); + } + : undefined, + }); + + // ------------------------------------------------------------------------- + // Summary + // ------------------------------------------------------------------------- + + console.log(''); + ConsoleFormatter.success(`Translated locale '${targetLocale}' in collection '${collectionName}'`); + ConsoleFormatter.keyValue('Translated', result.translatedCount); + ConsoleFormatter.keyValue('Skipped (ICU)', result.skippedCount); + ConsoleFormatter.keyValue('Failed', result.failedCount); + + if (result.failures.length > 0) { + console.log(''); + ConsoleFormatter.section('Failures'); + for (const failure of result.failures) { + ConsoleFormatter.indent(`${failure.key}: ${failure.error}`); + } + } + + if (result.failedCount > 0) { + process.exit(1); + } + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + ConsoleFormatter.error(`Translation failed: ${message}`); + process.exit(1); + } +} diff --git a/apps/cli/src/main.ts b/apps/cli/src/main.ts index 176c22ed..f35cbd36 100644 --- a/apps/cli/src/main.ts +++ b/apps/cli/src/main.ts @@ -62,6 +62,26 @@ program await deleteCollectionCommand(options); }); +program + .command('add-locale') + .description('Add a locale to a collection and backfill all existing resources') + .option('--collection ', 'Name of the collection') + .option('--locale ', 'Locale to add (e.g., fr-ca, de, es)') + .action(async (options) => { + const { addLocaleCommand } = await import('./commands/add-locale'); + await addLocaleCommand(options); + }); + +program + .command('remove-locale') + .description('Remove a locale from a collection and purge all locale data') + .option('--collection ', 'Name of the collection') + .option('--locale ', 'Locale to remove') + .action(async (options) => { + const { removeLocaleCommand } = await import('./commands/remove-locale'); + await removeLocaleCommand(options); + }); + program .command('add-resource') .description('Add a translation resource to a collection') @@ -136,6 +156,17 @@ program await normalizeCommand(options); }); +program + .command('translate-locale') + .description('Auto-translate all new/stale resources for a target locale') + .option('--collection ', 'Collection name') + .option('--locale ', 'Target locale to translate') + .option('--verbose', 'Show per-batch progress') + .action(async (options) => { + const { translateLocaleCommand } = await import('./commands/translate-locale'); + await translateLocaleCommand(options); + }); + program .command('bundle') .description('Generate translation bundles for deployment') diff --git a/apps/tracker/src/app/app.config.ts b/apps/tracker/src/app/app.config.ts index bf83398c..fa41c332 100644 --- a/apps/tracker/src/app/app.config.ts +++ b/apps/tracker/src/app/app.config.ts @@ -19,7 +19,7 @@ export const appConfig: ApplicationConfig = { provideHttpClient(), provideTransloco({ config: { - availableLangs: ['en', 'es', 'fr-ca'], + availableLangs: ['en', 'es', 'fr-ca', 'ru', 'ja', 'de'], defaultLang: 'en', reRenderOnLangChange: true, prodMode: !isDevMode(), diff --git a/apps/tracker/src/app/shared/services/locale.service.ts b/apps/tracker/src/app/shared/services/locale.service.ts index 06514b08..82252913 100644 --- a/apps/tracker/src/app/shared/services/locale.service.ts +++ b/apps/tracker/src/app/shared/services/locale.service.ts @@ -2,7 +2,7 @@ import { Injectable, signal, inject, PLATFORM_ID } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; import { TranslocoService } from '@jsverse/transloco'; -export type LocaleCode = 'en' | 'es' | 'fr-ca'; +export type LocaleCode = 'en' | 'es' | 'fr-ca' | 'ru' | 'ja' | 'de'; export interface LocaleOption { readonly code: LocaleCode; @@ -16,6 +16,9 @@ const AVAILABLE_LOCALES: readonly LocaleOption[] = [ { code: 'en', displayName: 'English' }, { code: 'es', displayName: 'Español' }, { code: 'fr-ca', displayName: 'Français (CA)' }, + { code: 'ru', displayName: 'Русский' }, + { code: 'ja', displayName: '日本語' }, + { code: 'de', displayName: 'Deutsch' }, ] as const; const VALID_LOCALE_CODES = new Set(AVAILABLE_LOCALES.map((l) => l.code)); diff --git a/apps/tracker/src/i18n/app/footer/resource_entries.json b/apps/tracker/src/i18n/app/footer/resource_entries.json index e470340b..396dab19 100644 --- a/apps/tracker/src/i18n/app/footer/resource_entries.json +++ b/apps/tracker/src/i18n/app/footer/resource_entries.json @@ -4,34 +4,49 @@ "comment": "Footer attribution text; SimonCodes-CA is a brand name and should not be translated", "tags": ["app"], "es": "Herramientas de SimonCodes-CA", - "fr-ca": "Outils de SimonCodes-CA" + "fr-ca": "Outils de SimonCodes-CA", + "ru": "Инструменты от SimonCodes-CA", + "ja": "SimonCodes-CAによるツール", + "de": "Tools von SimonCodes-CA" }, "githubTitle": { "source": "GitHub Repository", "comment": "Tooltip/title for the GitHub link in the footer", "tags": ["app"], "es": "Repositorio de GitHub", - "fr-ca": "Dépôt GitHub" + "fr-ca": "Dépôt GitHub", + "ru": "Репозиторий GitHub", + "ja": "GitHubリポジトリ", + "de": "GitHub-Repository" }, "githubLabel": { "source": "GitHub", "comment": "Visible label for the GitHub link in the footer", "tags": ["app"], "es": "GitHub", - "fr-ca": "GitHub" + "fr-ca": "GitHub", + "ru": "GitHub", + "ja": "GitHub", + "de": "GitHub" }, "issuesTitle": { "source": "Report an Issue", "comment": "Tooltip/title for the Issues link in the footer", "tags": ["app"], "es": "Informar un problema", - "fr-ca": "Signaler un problème" + "fr-ca": "Signaler un problème", + "ru": "Сообщить о проблеме", + "ja": "問題を報告する", + "de": "Problem melden" }, "issuesLabel": { "source": "Issues", "comment": "Visible label for the Issues link in the footer", "tags": ["app"], "es": "Asuntos", - "fr-ca": "Problèmes" + "fr-ca": "Problèmes", + "ru": "Проблемы", + "ja": "問題", + "de": "Probleme" } } diff --git a/apps/tracker/src/i18n/app/footer/tracker_meta.json b/apps/tracker/src/i18n/app/footer/tracker_meta.json index fb04a1bd..7ad92f4d 100644 --- a/apps/tracker/src/i18n/app/footer/tracker_meta.json +++ b/apps/tracker/src/i18n/app/footer/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "3b5b0ef2d1ba39310908b2533bfad938", "baseChecksum": "228e177a7df025238b894f2ae0026f34", "status": "translated" + }, + "ru": { + "checksum": "bff63c3ad261cf3012d39009a567b8d2", + "baseChecksum": "228e177a7df025238b894f2ae0026f34", + "status": "translated" + }, + "ja": { + "checksum": "5094ff9d5b9514b745dd2fb92f16ff3b", + "baseChecksum": "228e177a7df025238b894f2ae0026f34", + "status": "translated" + }, + "de": { + "checksum": "7c0be44fa717402e31bf6806b3cff5c2", + "baseChecksum": "228e177a7df025238b894f2ae0026f34", + "status": "translated" } }, "githubTitle": { @@ -27,6 +42,21 @@ "checksum": "6dec98956e678475c578da6924a7b582", "baseChecksum": "cf08730d37f83da9e97ca3262bf7072d", "status": "translated" + }, + "ru": { + "checksum": "4e7b4d27eeda52dff555a4c657e5dd96", + "baseChecksum": "cf08730d37f83da9e97ca3262bf7072d", + "status": "translated" + }, + "ja": { + "checksum": "12a12fb5f7e5802e5b4c8a450b719c14", + "baseChecksum": "cf08730d37f83da9e97ca3262bf7072d", + "status": "translated" + }, + "de": { + "checksum": "c638b7f7dbc525cacfb36111a77206df", + "baseChecksum": "cf08730d37f83da9e97ca3262bf7072d", + "status": "translated" } }, "githubLabel": { @@ -42,6 +72,21 @@ "checksum": "d3b7c913cd04ebfec0e9ec32cb6fd58c", "baseChecksum": "d3b7c913cd04ebfec0e9ec32cb6fd58c", "status": "translated" + }, + "ru": { + "checksum": "d3b7c913cd04ebfec0e9ec32cb6fd58c", + "baseChecksum": "d3b7c913cd04ebfec0e9ec32cb6fd58c", + "status": "translated" + }, + "ja": { + "checksum": "d3b7c913cd04ebfec0e9ec32cb6fd58c", + "baseChecksum": "d3b7c913cd04ebfec0e9ec32cb6fd58c", + "status": "translated" + }, + "de": { + "checksum": "d3b7c913cd04ebfec0e9ec32cb6fd58c", + "baseChecksum": "d3b7c913cd04ebfec0e9ec32cb6fd58c", + "status": "translated" } }, "issuesTitle": { @@ -57,6 +102,21 @@ "checksum": "5238d59077988c93ae554981b20fc64e", "baseChecksum": "0c6d9ab23098fd3e876c216fe1ca7ffc", "status": "translated" + }, + "ru": { + "checksum": "0949cf4c28d447f70367d086dec62847", + "baseChecksum": "0c6d9ab23098fd3e876c216fe1ca7ffc", + "status": "translated" + }, + "ja": { + "checksum": "655422ca284cf1a1aabf2ce72ffb66f7", + "baseChecksum": "0c6d9ab23098fd3e876c216fe1ca7ffc", + "status": "translated" + }, + "de": { + "checksum": "d3ca3d5f69058ef4267255fe4b242393", + "baseChecksum": "0c6d9ab23098fd3e876c216fe1ca7ffc", + "status": "translated" } }, "issuesLabel": { @@ -72,6 +132,21 @@ "checksum": "e040a699fc6d0d5808cfdaf3d1fa7146", "baseChecksum": "80b768b15c3693e345a436b9dc0ea36f", "status": "translated" + }, + "ru": { + "checksum": "f9890ec0744946bb63769a8bebab69d3", + "baseChecksum": "80b768b15c3693e345a436b9dc0ea36f", + "status": "translated" + }, + "ja": { + "checksum": "25486ad4e541ea9a04632f8c28ba14f8", + "baseChecksum": "80b768b15c3693e345a436b9dc0ea36f", + "status": "translated" + }, + "de": { + "checksum": "20b97fe763e2c83e86ad13c5deab2793", + "baseChecksum": "80b768b15c3693e345a436b9dc0ea36f", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/app/resource_entries.json b/apps/tracker/src/i18n/app/resource_entries.json index b3f9ae51..3b64595d 100644 --- a/apps/tracker/src/i18n/app/resource_entries.json +++ b/apps/tracker/src/i18n/app/resource_entries.json @@ -4,6 +4,9 @@ "comment": "Accessibility link at top of page for keyboard navigation", "tags": ["app"], "es": "Saltar al contenido principal", - "fr-ca": "Passer au contenu principal" + "fr-ca": "Passer au contenu principal", + "ru": "Перейти к основному содержимому", + "ja": "メインコンテンツへスキップ", + "de": "Zum Hauptinhalt springen" } } diff --git a/apps/tracker/src/i18n/app/tracker_meta.json b/apps/tracker/src/i18n/app/tracker_meta.json index 788352ee..d440c8d5 100644 --- a/apps/tracker/src/i18n/app/tracker_meta.json +++ b/apps/tracker/src/i18n/app/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "1b832d4bc3ea43f017b16032aff04f57", "baseChecksum": "cc367b544fab23df0ddaf982fb1445b5", "status": "translated" + }, + "ru": { + "checksum": "26915f78356945d1b403f0c694a320b7", + "baseChecksum": "cc367b544fab23df0ddaf982fb1445b5", + "status": "translated" + }, + "ja": { + "checksum": "cd757fa937839fce931945543637e8a4", + "baseChecksum": "cc367b544fab23df0ddaf982fb1445b5", + "status": "translated" + }, + "de": { + "checksum": "26702fe976ca5f8e477b4ddb1a7736a3", + "baseChecksum": "cc367b544fab23df0ddaf982fb1445b5", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/density/resource_entries.json b/apps/tracker/src/i18n/browser/density/resource_entries.json index b2b65e9b..a7e4bcec 100644 --- a/apps/tracker/src/i18n/browser/density/resource_entries.json +++ b/apps/tracker/src/i18n/browser/density/resource_entries.json @@ -4,34 +4,49 @@ "comment": "Tooltip for compact density mode toggle button", "tags": ["browser"], "es": "Compacto: vista de 2 líneas, alta densidad", - "fr-ca": "Compact — affichage sur 2 lignes, haute densité" + "fr-ca": "Compact — affichage sur 2 lignes, haute densité", + "ru": "Компактный — двухстрочный режим отображения, высокая плотность пикселей.", + "ja": "コンパクト - 2行表示、高密度", + "de": "Kompakt – 2-Zeilen-Ansicht, hohe Dichte" }, "fullTooltip": { "source": "Full — detailed view with comments and all locales", "comment": "Tooltip for full density mode toggle button", "tags": ["browser"], "es": "Completo: vista detallada con comentarios y todas las configuraciones regionales", - "fr-ca": "Vue complète et détaillée avec commentaires et toutes les langues" + "fr-ca": "Vue complète et détaillée avec commentaires et toutes les langues", + "ru": "Полный — подробный просмотр с комментариями и всеми локалями.", + "ja": "完全版 — コメントとすべての地域を含む詳細表示", + "de": "Vollständige – detaillierte Ansicht mit Kommentaren und allen Standorten" }, "modeAriaLabel": { "source": "Density mode", "comment": "Aria-label for the density mode button toggle group in the translation header", "tags": ["browser"], "es": "Modo de densidad", - "fr-ca": "Mode de densité" + "fr-ca": "Mode de densité", + "ru": "Режим плотности", + "ja": "密度モード", + "de": "Dichtemodus" }, "compactAriaLabel": { "source": "Compact density", "comment": "Aria-label for the compact density toggle button", "tags": ["browser"], "es": "Densidad compacta", - "fr-ca": "Densité compacte" + "fr-ca": "Densité compacte", + "ru": "Плотная компактность", + "ja": "高密度", + "de": "Kompakte Dichte" }, "fullAriaLabel": { "source": "Full density", "comment": "Aria-label for the full density toggle button", "tags": ["browser"], "es": "Densidad completa", - "fr-ca": "Densité maximale" + "fr-ca": "Densité maximale", + "ru": "Полная плотность", + "ja": "完全密度", + "de": "Volle Dichte" } } diff --git a/apps/tracker/src/i18n/browser/density/tracker_meta.json b/apps/tracker/src/i18n/browser/density/tracker_meta.json index bfa76b92..21e85189 100644 --- a/apps/tracker/src/i18n/browser/density/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/density/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "025c48513c4533a98b4139d4e8f67586", "baseChecksum": "99ec7955eb135928d0c239b3521140c3", "status": "translated" + }, + "ru": { + "checksum": "7a9e12bfd5f2b9d7d515dd12bc1e1648", + "baseChecksum": "99ec7955eb135928d0c239b3521140c3", + "status": "translated" + }, + "ja": { + "checksum": "8d4293530065fed7ec05336a71a83410", + "baseChecksum": "99ec7955eb135928d0c239b3521140c3", + "status": "translated" + }, + "de": { + "checksum": "046eb75024ccb0f2e051f68baf8d3d47", + "baseChecksum": "99ec7955eb135928d0c239b3521140c3", + "status": "translated" } }, "fullTooltip": { @@ -27,6 +42,21 @@ "checksum": "7b767ce788c57fcd14e10cdb49971793", "baseChecksum": "4f0dbd02ebc750568b8c7fa10cc9e6b7", "status": "translated" + }, + "ru": { + "checksum": "9253533a9c6f633f47a7a31e6d70967f", + "baseChecksum": "4f0dbd02ebc750568b8c7fa10cc9e6b7", + "status": "translated" + }, + "ja": { + "checksum": "d30b5f58f77896dd48a5faac933aeb4f", + "baseChecksum": "4f0dbd02ebc750568b8c7fa10cc9e6b7", + "status": "translated" + }, + "de": { + "checksum": "2df1b96af1e2c0fbbbe3e8978dd36001", + "baseChecksum": "4f0dbd02ebc750568b8c7fa10cc9e6b7", + "status": "translated" } }, "modeAriaLabel": { @@ -42,6 +72,21 @@ "checksum": "a8deb5c9ddf138a8c9a5e5380b4b8840", "baseChecksum": "cee89fa354411866e20092652b6b8b07", "status": "translated" + }, + "ru": { + "checksum": "d2294477be4875018ebaf26767da8417", + "baseChecksum": "cee89fa354411866e20092652b6b8b07", + "status": "translated" + }, + "ja": { + "checksum": "2fabe94b844462169d8c335da7ef8453", + "baseChecksum": "cee89fa354411866e20092652b6b8b07", + "status": "translated" + }, + "de": { + "checksum": "5640b797f0dc0af8a6d98e01db2b4758", + "baseChecksum": "cee89fa354411866e20092652b6b8b07", + "status": "translated" } }, "compactAriaLabel": { @@ -57,6 +102,21 @@ "checksum": "44b0660e4de6ad0ce2f92157587e7436", "baseChecksum": "e44615f2f134cfe073e2960672aa7489", "status": "translated" + }, + "ru": { + "checksum": "20eb9947c9abcea7710df5bd48843039", + "baseChecksum": "e44615f2f134cfe073e2960672aa7489", + "status": "translated" + }, + "ja": { + "checksum": "f7dcc0ac9e61ac8abd64bfcc171be0a0", + "baseChecksum": "e44615f2f134cfe073e2960672aa7489", + "status": "translated" + }, + "de": { + "checksum": "d9564921fc6e170cf8761767746d8472", + "baseChecksum": "e44615f2f134cfe073e2960672aa7489", + "status": "translated" } }, "fullAriaLabel": { @@ -72,6 +132,21 @@ "checksum": "903502f8b1f4972daef6f8d171fd5b71", "baseChecksum": "02474f847ab2138e522a31349e7aec0f", "status": "translated" + }, + "ru": { + "checksum": "f00efad4d0bd99baff6504bfb45dc3e8", + "baseChecksum": "02474f847ab2138e522a31349e7aec0f", + "status": "translated" + }, + "ja": { + "checksum": "82ad02096571402a315e21e5b3b7a9cd", + "baseChecksum": "02474f847ab2138e522a31349e7aec0f", + "status": "translated" + }, + "de": { + "checksum": "bc4897f511be5e69c78246ffda249d62", + "baseChecksum": "02474f847ab2138e522a31349e7aec0f", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/dialog/deleteFolder/resource_entries.json b/apps/tracker/src/i18n/browser/dialog/deleteFolder/resource_entries.json index f019db43..2d28af17 100644 --- a/apps/tracker/src/i18n/browser/dialog/deleteFolder/resource_entries.json +++ b/apps/tracker/src/i18n/browser/dialog/deleteFolder/resource_entries.json @@ -4,13 +4,19 @@ "comment": "Title of the confirmation dialog when deleting a folder", "tags": ["browser"], "es": "Eliminar carpeta", - "fr-ca": "Supprimer le dossier" + "fr-ca": "Supprimer le dossier", + "ru": "Удалить папку", + "ja": "フォルダを削除する", + "de": "Ordner löschen" }, "messageX": { "source": "Delete \"{name}\" and all its contents?", "comment": "Confirmation message when deleting a folder, interpolated with the folder name", "tags": ["browser"], "es": "¿Eliminar \"{name}\" y todo su contenido?", - "fr-ca": "Supprimer \"{name}\" et tout son contenu ?" + "fr-ca": "Supprimer \"{name}\" et tout son contenu ?", + "ru": "Удалить \"{name}\" и всё его содержимое?", + "ja": "「{name}」とその内容をすべて削除しますか?", + "de": "\"{name}\" und seinen gesamten Inhalt löschen?" } } diff --git a/apps/tracker/src/i18n/browser/dialog/deleteFolder/tracker_meta.json b/apps/tracker/src/i18n/browser/dialog/deleteFolder/tracker_meta.json index d5dc682d..0a6b77bb 100644 --- a/apps/tracker/src/i18n/browser/dialog/deleteFolder/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/dialog/deleteFolder/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "7710100989dd0487c8751db81bca3901", "baseChecksum": "991e322cd8225c369a963bb60b0a9688", "status": "translated" + }, + "ru": { + "checksum": "134da182ff56e65fa18a6e704a316e02", + "baseChecksum": "991e322cd8225c369a963bb60b0a9688", + "status": "translated" + }, + "ja": { + "checksum": "562f7fe2b9f1c1f4ebc16d39c39f8b7f", + "baseChecksum": "991e322cd8225c369a963bb60b0a9688", + "status": "translated" + }, + "de": { + "checksum": "3f2ba266360c45c327c8a3728b3fe199", + "baseChecksum": "991e322cd8225c369a963bb60b0a9688", + "status": "translated" } }, "messageX": { @@ -27,6 +42,21 @@ "checksum": "db2c2daa6645cda8f415809bbec8bba2", "baseChecksum": "5f0ed1d8bc9815b6bc420bf0aee99c6a", "status": "stale" + }, + "ru": { + "checksum": "8820a2771dfcb540ed217136d4e67460", + "baseChecksum": "5f0ed1d8bc9815b6bc420bf0aee99c6a", + "status": "translated" + }, + "ja": { + "checksum": "67608fe71d95541b9933d39a2e7cb626", + "baseChecksum": "5f0ed1d8bc9815b6bc420bf0aee99c6a", + "status": "translated" + }, + "de": { + "checksum": "bdf9a9dc7cc399f9a834a63145b6a259", + "baseChecksum": "5f0ed1d8bc9815b6bc420bf0aee99c6a", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/dialog/deleteResource/resource_entries.json b/apps/tracker/src/i18n/browser/dialog/deleteResource/resource_entries.json index 88995a4d..ab36805e 100644 --- a/apps/tracker/src/i18n/browser/dialog/deleteResource/resource_entries.json +++ b/apps/tracker/src/i18n/browser/dialog/deleteResource/resource_entries.json @@ -4,13 +4,19 @@ "comment": "Title of the confirmation dialog when deleting a resource", "tags": ["browser"], "es": "Eliminar recurso", - "fr-ca": "Supprimer la ressource" + "fr-ca": "Supprimer la ressource", + "ru": "Удалить ресурс", + "ja": "リソースを削除する", + "de": "Ressource löschen" }, "messageX": { "source": "Are you sure you want to delete the resource \"{key}\"? This action cannot be undone.", "comment": "Confirmation message when deleting a resource, interpolated with the resource key", "tags": ["browser"], "es": "¿Seguro que desea eliminar el recurso \"{key}\"? Esta acción no se puede deshacer.", - "fr-ca": "Êtes-vous certain de vouloir supprimer la ressource « {key} » ? Cette action est irréversible." + "fr-ca": "Êtes-vous certain de vouloir supprimer la ressource « {key} » ? Cette action est irréversible.", + "ru": "Вы уверены, что хотите удалить ресурс \"{key}\"? Это действие необратимо.", + "ja": "リソース「{key}」を削除してもよろしいですか?この操作は元に戻せません。", + "de": "Sind Sie sicher, dass Sie die Ressource \"{key}\" löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden." } } diff --git a/apps/tracker/src/i18n/browser/dialog/deleteResource/tracker_meta.json b/apps/tracker/src/i18n/browser/dialog/deleteResource/tracker_meta.json index c5032198..e96aa1f4 100644 --- a/apps/tracker/src/i18n/browser/dialog/deleteResource/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/dialog/deleteResource/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "a56e2e5c2d55f4ee33b68aa628d0fa3e", "baseChecksum": "7091aa93a78122401125a34800f9a1ac", "status": "translated" + }, + "ru": { + "checksum": "30058d276a708b6f046031fed91baf35", + "baseChecksum": "7091aa93a78122401125a34800f9a1ac", + "status": "translated" + }, + "ja": { + "checksum": "aa7622a8f3cdec64553738d3a180ade9", + "baseChecksum": "7091aa93a78122401125a34800f9a1ac", + "status": "translated" + }, + "de": { + "checksum": "6f34a1687a7fbb11839ff67195a1ebf3", + "baseChecksum": "7091aa93a78122401125a34800f9a1ac", + "status": "translated" } }, "messageX": { @@ -27,6 +42,21 @@ "checksum": "8c4dc291d4e9879be2c9a5e2faae5df7", "baseChecksum": "ac83571aec2e065433da7fd905696d5f", "status": "stale" + }, + "ru": { + "checksum": "80a3d311146ea968e4debaa343339da6", + "baseChecksum": "ac83571aec2e065433da7fd905696d5f", + "status": "translated" + }, + "ja": { + "checksum": "8fc4d60dca252625969f6139dc19c349", + "baseChecksum": "ac83571aec2e065433da7fd905696d5f", + "status": "translated" + }, + "de": { + "checksum": "26e419957dd41dc1529aa1f4e1db1cfe", + "baseChecksum": "ac83571aec2e065433da7fd905696d5f", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/dialog/moveFolder/resource_entries.json b/apps/tracker/src/i18n/browser/dialog/moveFolder/resource_entries.json index eebc8b99..0ceb6aa7 100644 --- a/apps/tracker/src/i18n/browser/dialog/moveFolder/resource_entries.json +++ b/apps/tracker/src/i18n/browser/dialog/moveFolder/resource_entries.json @@ -4,13 +4,19 @@ "comment": "Title of the confirmation dialog when moving a folder", "tags": ["browser"], "es": "Mover carpeta", - "fr-ca": "Déplacer le dossier" + "fr-ca": "Déplacer le dossier", + "ru": "Переместить папку", + "ja": "フォルダーを移動する", + "de": "Ordner verschieben" }, "messageX": { "source": "Move folder \"{name}\" and all its contents to \"{dest}\"?", "comment": "Confirmation message when moving a folder, interpolated with folder name and destination", "tags": ["browser"], "es": "¿Mover la carpeta \"{name}\" y todo su contenido a \"{dest}\"?", - "fr-ca": "Déplacer le dossier \"{name}\" et tout son contenu vers \"{dest}\" ?" + "fr-ca": "Déplacer le dossier \"{name}\" et tout son contenu vers \"{dest}\" ?", + "ru": "Переместить папку \"{name}\" и все ее содержимое в \"{dest}\"?", + "ja": "フォルダ「{name}」とその中のすべての内容を「{dest}」に移動しますか?", + "de": "Ordner \"{name}\" und seinen gesamten Inhalt nach \"{dest}\" verschieben?" } } diff --git a/apps/tracker/src/i18n/browser/dialog/moveFolder/tracker_meta.json b/apps/tracker/src/i18n/browser/dialog/moveFolder/tracker_meta.json index b8ee7c7f..05a4647a 100644 --- a/apps/tracker/src/i18n/browser/dialog/moveFolder/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/dialog/moveFolder/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "b3009170157da9eb03bd31db89b85c04", "baseChecksum": "1c10ed990d6445081dfd3828812355e5", "status": "translated" + }, + "ru": { + "checksum": "2506a41030af5ca68c85b9a0f7adef40", + "baseChecksum": "1c10ed990d6445081dfd3828812355e5", + "status": "translated" + }, + "ja": { + "checksum": "dcb7ba7c1d903a09f83b7fd2ae8d18d9", + "baseChecksum": "1c10ed990d6445081dfd3828812355e5", + "status": "translated" + }, + "de": { + "checksum": "289e2d173d50d45e38b7e5c491459413", + "baseChecksum": "1c10ed990d6445081dfd3828812355e5", + "status": "translated" } }, "messageX": { @@ -27,6 +42,21 @@ "checksum": "8f741688880541fe5c8fc950c9006d6f", "baseChecksum": "b7778a68166ffe0dab524997ad6b3bfd", "status": "stale" + }, + "ru": { + "checksum": "1f0f24b76f5ae12fc19a83863b053b7b", + "baseChecksum": "b7778a68166ffe0dab524997ad6b3bfd", + "status": "translated" + }, + "ja": { + "checksum": "a6606371456d1428db6cd20ed4c740bc", + "baseChecksum": "b7778a68166ffe0dab524997ad6b3bfd", + "status": "translated" + }, + "de": { + "checksum": "b1cd3d673aa2697fddd1ad90fa4e914a", + "baseChecksum": "b7778a68166ffe0dab524997ad6b3bfd", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/folderInput/resource_entries.json b/apps/tracker/src/i18n/browser/folderInput/resource_entries.json index 5c6868e7..4c81441a 100644 --- a/apps/tracker/src/i18n/browser/folderInput/resource_entries.json +++ b/apps/tracker/src/i18n/browser/folderInput/resource_entries.json @@ -4,20 +4,29 @@ "comment": "Placeholder text in the inline folder name input field", "tags": ["browser"], "es": "Nombre de la carpeta", - "fr-ca": "Nom du dossier" + "fr-ca": "Nom du dossier", + "ru": "Название папки", + "ja": "フォルダ名", + "de": "Ordnername" }, "nameRequired": { "source": "Folder name is required", "comment": "Validation error when folder name input is empty", "tags": ["browser"], "es": "El nombre de la carpeta es obligatorio", - "fr-ca": "Le nom du dossier est requis." + "fr-ca": "Le nom du dossier est requis.", + "ru": "Название папки обязательно для указания.", + "ja": "フォルダ名は必須です", + "de": "Ein Ordnername ist erforderlich." }, "namePatternError": { "source": "Only letters, numbers, dashes, and underscores allowed", "comment": "Validation error when folder name contains invalid characters", "tags": ["browser"], "es": "Solo se permiten letras, números, guiones y guiones bajos.", - "fr-ca": "Seules les lettres, les chiffres, les tirets et les traits de soulignement sont autorisés." + "fr-ca": "Seules les lettres, les chiffres, les tirets et les traits de soulignement sont autorisés.", + "ru": "Разрешается использовать только буквы, цифры, дефисы и подчеркивания.", + "ja": "使用できる文字、数字、ハイフン、アンダースコアのみです。", + "de": "Nur Buchstaben, Zahlen, Bindestriche und Unterstriche sind erlaubt." } } diff --git a/apps/tracker/src/i18n/browser/folderInput/tracker_meta.json b/apps/tracker/src/i18n/browser/folderInput/tracker_meta.json index 3562d4c2..bdfad5dd 100644 --- a/apps/tracker/src/i18n/browser/folderInput/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/folderInput/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "49e66c56efe7e867c359433ad728ac90", "baseChecksum": "710417c4e57a6a01500fe4c0c448ce3d", "status": "translated" + }, + "ru": { + "checksum": "16f4890b29f8f7a793855f9b5ac7724b", + "baseChecksum": "710417c4e57a6a01500fe4c0c448ce3d", + "status": "translated" + }, + "ja": { + "checksum": "8e075835352ff89cf377cd81d97900be", + "baseChecksum": "710417c4e57a6a01500fe4c0c448ce3d", + "status": "translated" + }, + "de": { + "checksum": "7b5f28765ae3a0754c994c5536bd57f3", + "baseChecksum": "710417c4e57a6a01500fe4c0c448ce3d", + "status": "translated" } }, "nameRequired": { @@ -27,6 +42,21 @@ "checksum": "014a2178e84ad240b882e4adff49127e", "baseChecksum": "9e8e01dde2a46cfe2812ea89bbd9b6a9", "status": "translated" + }, + "ru": { + "checksum": "52eded3a97c8d5c4ce2d1becc044f39a", + "baseChecksum": "9e8e01dde2a46cfe2812ea89bbd9b6a9", + "status": "translated" + }, + "ja": { + "checksum": "efab011f753b9e16f84893e0af2a520b", + "baseChecksum": "9e8e01dde2a46cfe2812ea89bbd9b6a9", + "status": "translated" + }, + "de": { + "checksum": "cb538b3f72f91ed52aac9ae8f414773f", + "baseChecksum": "9e8e01dde2a46cfe2812ea89bbd9b6a9", + "status": "translated" } }, "namePatternError": { @@ -42,6 +72,21 @@ "checksum": "a83915a6f013b0e5f19b3a807145e8eb", "baseChecksum": "6ffb87ace7727c5d44238c324f75a757", "status": "translated" + }, + "ru": { + "checksum": "b4dfbb94d2174527e3e49435e8d37cdf", + "baseChecksum": "6ffb87ace7727c5d44238c324f75a757", + "status": "translated" + }, + "ja": { + "checksum": "e3d0f4d45bbf2ac57c31082d458ee87a", + "baseChecksum": "6ffb87ace7727c5d44238c324f75a757", + "status": "translated" + }, + "de": { + "checksum": "1bc04ac173ee13350abab5aed9f81366", + "baseChecksum": "6ffb87ace7727c5d44238c324f75a757", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/folderNode/resource_entries.json b/apps/tracker/src/i18n/browser/folderNode/resource_entries.json index 112cfecf..d024e431 100644 --- a/apps/tracker/src/i18n/browser/folderNode/resource_entries.json +++ b/apps/tracker/src/i18n/browser/folderNode/resource_entries.json @@ -4,27 +4,39 @@ "comment": "Badge shown on a folder node immediately after it is created", "tags": ["browser"], "es": "Nuevo", - "fr-ca": "Nouveau" + "fr-ca": "Nouveau", + "ru": "Новый", + "ja": "新しい", + "de": "Neu" }, "folderAriaLabelX": { "source": "Folder { name }", "comment": "Aria-label for a folder node in the tree. { name } is the folder name", "tags": ["browser"], "es": "Carpeta { nombre }", - "fr-ca": "Dossier { nom }" + "fr-ca": "Dossier { nom }", + "ru": "Папка { имя }", + "ja": "フォルダ {名前}", + "de": "Ordner { Name }" }, "dragToMoveFolderAriaLabel": { "source": "Drag to move folder", "comment": "Aria-label for the drag handle icon on a folder node", "tags": ["browser"], "es": "Arrastrar para mover la carpeta", - "fr-ca": "Faites glisser pour déplacer le dossier" + "fr-ca": "Faites glisser pour déplacer le dossier", + "ru": "Перетащите, чтобы переместить папку.", + "ja": "フォルダをドラッグして移動", + "de": "Ordner per Drag & Drop verschieben" }, "deleteFolderAriaLabelX": { "source": "Delete folder { name }", "comment": "Aria-label for the delete button on a folder node. { name } is the folder name", "tags": ["browser"], "es": "Eliminar carpeta { nombre }", - "fr-ca": "Supprimer le dossier { nom }" + "fr-ca": "Supprimer le dossier { nom }", + "ru": "Удалить папку {имя}", + "ja": "フォルダ {名前} を削除します", + "de": "Ordner { Name } löschen" } } diff --git a/apps/tracker/src/i18n/browser/folderNode/tracker_meta.json b/apps/tracker/src/i18n/browser/folderNode/tracker_meta.json index 2ed93420..8bd9b1eb 100644 --- a/apps/tracker/src/i18n/browser/folderNode/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/folderNode/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "9ea17b10f506b881fed906aab0a50f8d", "baseChecksum": "03c2e7e41ffc181a4e84080b4710e81e", "status": "translated" + }, + "ru": { + "checksum": "97ae6e0bca16b37dbdc5e324d0ecaf60", + "baseChecksum": "03c2e7e41ffc181a4e84080b4710e81e", + "status": "translated" + }, + "ja": { + "checksum": "ad4b0bd55882d4f7164630d4158d3c39", + "baseChecksum": "03c2e7e41ffc181a4e84080b4710e81e", + "status": "translated" + }, + "de": { + "checksum": "e85a2f1d6de3e3b0e71b1a2e19952659", + "baseChecksum": "03c2e7e41ffc181a4e84080b4710e81e", + "status": "translated" } }, "folderAriaLabelX": { @@ -27,6 +42,21 @@ "checksum": "aaf5400b2f5e2d034201e563be05efd9", "baseChecksum": "2807ee06f9cee829069ff722e0076f63", "status": "translated" + }, + "ru": { + "checksum": "6c01295f55133a6381deaa9b19f298ed", + "baseChecksum": "2807ee06f9cee829069ff722e0076f63", + "status": "translated" + }, + "ja": { + "checksum": "b279d2cfed0ba56b787c597461de81bb", + "baseChecksum": "2807ee06f9cee829069ff722e0076f63", + "status": "translated" + }, + "de": { + "checksum": "9a4eda48758fb87e7899ab93439e897c", + "baseChecksum": "2807ee06f9cee829069ff722e0076f63", + "status": "translated" } }, "dragToMoveFolderAriaLabel": { @@ -42,6 +72,21 @@ "checksum": "99ddcde95a1ca2801821826f38b538b4", "baseChecksum": "621cc4d814e3af59119d9cd80bf87908", "status": "translated" + }, + "ru": { + "checksum": "c02424c40807563ededc26e70ee7764d", + "baseChecksum": "621cc4d814e3af59119d9cd80bf87908", + "status": "translated" + }, + "ja": { + "checksum": "08c276e541d0aa7d1836c9ba7eb7414e", + "baseChecksum": "621cc4d814e3af59119d9cd80bf87908", + "status": "translated" + }, + "de": { + "checksum": "a6baabf4e4c2e5a29693e28407a82459", + "baseChecksum": "621cc4d814e3af59119d9cd80bf87908", + "status": "translated" } }, "deleteFolderAriaLabelX": { @@ -57,6 +102,21 @@ "checksum": "1b45ccc834ef6f20800df6bb073ab938", "baseChecksum": "fa3c80ac936464dfdfec9ddb30c5278b", "status": "translated" + }, + "ru": { + "checksum": "4ece16ddf1acf1166eda7b86121240de", + "baseChecksum": "fa3c80ac936464dfdfec9ddb30c5278b", + "status": "translated" + }, + "ja": { + "checksum": "5f068424ca259e11241a275b3e4887b1", + "baseChecksum": "fa3c80ac936464dfdfec9ddb30c5278b", + "status": "translated" + }, + "de": { + "checksum": "0bf5b9676022deb80311c34c42e009e3", + "baseChecksum": "fa3c80ac936464dfdfec9ddb30c5278b", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/folderPicker/resource_entries.json b/apps/tracker/src/i18n/browser/folderPicker/resource_entries.json index 0642cad6..6be31fb5 100644 --- a/apps/tracker/src/i18n/browser/folderPicker/resource_entries.json +++ b/apps/tracker/src/i18n/browser/folderPicker/resource_entries.json @@ -4,90 +4,129 @@ "comment": "Aria-label for a folder node in the picker tree", "tags": ["browser"], "es": "Carpeta {name}", - "fr-ca": "Dossier {name}" + "fr-ca": "Dossier {name}", + "ru": "Папка {name}", + "ja": "フォルダ {name}", + "de": "Ordner {name}" }, "collapse": { "source": "Collapse", "comment": "Aria-label for collapse button on a folder tree node", "tags": ["browser"], "es": "Colapsar", - "fr-ca": "Effondrement" + "fr-ca": "Effondrement", + "ru": "Крах", + "ja": "崩壊", + "de": "Zusammenbruch" }, "expand": { "source": "Expand", "comment": "Aria-label for expand button on a folder tree node", "tags": ["browser"], "es": "Expandir", - "fr-ca": "Élargir" + "fr-ca": "Élargir", + "ru": "Расширять", + "ja": "拡大する", + "de": "Expandieren" }, "addSubfolderToX": { "source": "Add subfolder to {name}", "comment": "Aria-label for add subfolder button on a folder node", "tags": ["browser"], "es": "Agregar subcarpeta a {name}", - "fr-ca": "Ajouter un sous-dossier à {name}" + "fr-ca": "Ajouter un sous-dossier à {name}", + "ru": "Добавить подпапку в {name}", + "ja": "{name} にサブフォルダを追加します", + "de": "Füge einen Unterordner zu {name} hinzu." }, "folderLabel": { "source": "Folder:", "comment": "Label prefix for the selected folder path in the folder picker", "tags": ["browser"], "es": "Carpeta:", - "fr-ca": "Dossier :" + "fr-ca": "Dossier :", + "ru": "Папка:", + "ja": "フォルダ:", + "de": "Ordner:" }, "noFoldersYet": { "source": "No folders yet", "comment": "Empty state message in folder picker when there are no folders", "tags": ["browser"], "es": "No hay carpetas todavía", - "fr-ca": "Aucun dossier pour le moment" + "fr-ca": "Aucun dossier pour le moment", + "ru": "Папок пока нет.", + "ja": "まだフォルダはありません", + "de": "Noch keine Ordner" }, "createFirstFolder": { "source": "Create First Folder", "comment": "Button text to create the first folder when there are none", "tags": ["browser"], "es": "Crear la primera carpeta", - "fr-ca": "Créer le premier dossier" + "fr-ca": "Créer le premier dossier", + "ru": "Создать первую папку", + "ja": "最初のフォルダを作成する", + "de": "Ersten Ordner erstellen" }, "folderCreated": { "source": "Folder created successfully", "comment": "Snackbar message after creating a folder", "tags": ["browser"], "es": "Carpeta creada exitosamente", - "fr-ca": "Dossier créé avec succès" + "fr-ca": "Dossier créé avec succès", + "ru": "Папка успешно создана.", + "ja": "フォルダが正常に作成されました", + "de": "Ordner erfolgreich erstellt" }, "folderAlreadyExists": { "source": "Folder already exists", "comment": "Snackbar message when trying to create a folder that already exists", "tags": ["browser"], "es": "La carpeta ya existe", - "fr-ca": "Le dossier existe déjà." + "fr-ca": "Le dossier existe déjà.", + "ru": "Папка уже существует", + "ja": "フォルダは既に存在します", + "de": "Der Ordner existiert bereits." }, "createFolderFailed": { "source": "Failed to create folder", "comment": "Snackbar error message when folder creation fails", "tags": ["browser"], "es": "No se pudo crear la carpeta", - "fr-ca": "Impossible de créer le dossier" + "fr-ca": "Impossible de créer le dossier", + "ru": "Не удалось создать папку.", + "ja": "フォルダの作成に失敗しました", + "de": "Ordner konnte nicht erstellt werden" }, "rootLabel": { "source": "root", "comment": "Label displayed when the selected folder is the root (empty path)", "tags": ["browser"], "es": "raíz", - "fr-ca": "racine" + "fr-ca": "racine", + "ru": "корень", + "ja": "根", + "de": "Wurzel" }, "selectorAriaLabelX": { "source": "Folder selector, currently: { path }", "comment": "Aria-label for the folder picker header button. { path } is the currently selected folder path", "tags": ["browser"], "es": "Selector de carpeta, actualmente: { ruta }", - "fr-ca": "Sélecteur de dossier, présentement : { chemin }" + "fr-ca": "Sélecteur de dossier, présentement : { chemin }", + "ru": "Селектор папки, в данный момент: { путь }", + "ja": "フォルダセレクター、現在の値: { パス }", + "de": "Ordnerauswahl, aktuell: { Pfad }" }, "treeAriaLabel": { "source": "Folder tree", "comment": "Aria-label for the folder tree container in the folder picker", "tags": ["browser"], "es": "Árbol de carpetas", - "fr-ca": "Arborescence des dossiers" + "fr-ca": "Arborescence des dossiers", + "ru": "Дерево папок", + "ja": "フォルダーツリー", + "de": "Ordnerstruktur" } } diff --git a/apps/tracker/src/i18n/browser/folderPicker/tracker_meta.json b/apps/tracker/src/i18n/browser/folderPicker/tracker_meta.json index 52cc66fd..23cbda29 100644 --- a/apps/tracker/src/i18n/browser/folderPicker/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/folderPicker/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "579125b969a55e9f1429775d20e2faa5", "baseChecksum": "16708b0cacde01471507891eb88bcf2b", "status": "stale" + }, + "ru": { + "checksum": "91946bcd8bb4cbac5db6c724fee19b1f", + "baseChecksum": "16708b0cacde01471507891eb88bcf2b", + "status": "translated" + }, + "ja": { + "checksum": "eac7a0a1e12765c214b1085965f45fb7", + "baseChecksum": "16708b0cacde01471507891eb88bcf2b", + "status": "translated" + }, + "de": { + "checksum": "ea4bf7e72c09675cd73a2b718e4c4d45", + "baseChecksum": "16708b0cacde01471507891eb88bcf2b", + "status": "translated" } }, "collapse": { @@ -27,6 +42,21 @@ "checksum": "0296e4551eb2a71666f3b95299fabc4d", "baseChecksum": "2b31634e3cfef1bfdd7d0d2cdfdc3f9d", "status": "translated" + }, + "ru": { + "checksum": "f4c615603939c75033535b2c78761789", + "baseChecksum": "2b31634e3cfef1bfdd7d0d2cdfdc3f9d", + "status": "translated" + }, + "ja": { + "checksum": "043901ea2022bf1c3b7c9f1feeda07fd", + "baseChecksum": "2b31634e3cfef1bfdd7d0d2cdfdc3f9d", + "status": "translated" + }, + "de": { + "checksum": "dc87dfdb97b71708f80fe846b584186e", + "baseChecksum": "2b31634e3cfef1bfdd7d0d2cdfdc3f9d", + "status": "translated" } }, "expand": { @@ -42,6 +72,21 @@ "checksum": "0f16886ce9ef9bd31180b466a01600b1", "baseChecksum": "8098b34f582537833b36b58273c3545b", "status": "translated" + }, + "ru": { + "checksum": "b9db830bf9c8d16e36fcd353c4fb95e8", + "baseChecksum": "8098b34f582537833b36b58273c3545b", + "status": "translated" + }, + "ja": { + "checksum": "4615433abf3e1131172d9a8f5dffb2f2", + "baseChecksum": "8098b34f582537833b36b58273c3545b", + "status": "translated" + }, + "de": { + "checksum": "3a709ed8fde2281096eeb787ce715c47", + "baseChecksum": "8098b34f582537833b36b58273c3545b", + "status": "translated" } }, "addSubfolderToX": { @@ -57,6 +102,21 @@ "checksum": "7a3c0707dbd14091260a5aca97d25f02", "baseChecksum": "aa85d08e5c2011ca6a07c0db14c82de2", "status": "stale" + }, + "ru": { + "checksum": "da6ae24598b43f425bbeb36a05a35bed", + "baseChecksum": "aa85d08e5c2011ca6a07c0db14c82de2", + "status": "translated" + }, + "ja": { + "checksum": "157c9e9aa46efb7353525d7e13eedee9", + "baseChecksum": "aa85d08e5c2011ca6a07c0db14c82de2", + "status": "translated" + }, + "de": { + "checksum": "b3f017dde8b4c323a06ff5974626faf6", + "baseChecksum": "aa85d08e5c2011ca6a07c0db14c82de2", + "status": "translated" } }, "folderLabel": { @@ -72,6 +132,21 @@ "checksum": "c836c1633a42ce6abf860a6770e3fe9e", "baseChecksum": "5416b7cf9e33d63d7a7484a75e977dfa", "status": "translated" + }, + "ru": { + "checksum": "0bde293383ace742393f9d7ab4c6d6f2", + "baseChecksum": "5416b7cf9e33d63d7a7484a75e977dfa", + "status": "translated" + }, + "ja": { + "checksum": "7a2b94c75981c521deea7118a39b0c38", + "baseChecksum": "5416b7cf9e33d63d7a7484a75e977dfa", + "status": "translated" + }, + "de": { + "checksum": "00328b87c1f4b09e604c0d725ff1919f", + "baseChecksum": "5416b7cf9e33d63d7a7484a75e977dfa", + "status": "translated" } }, "noFoldersYet": { @@ -87,6 +162,21 @@ "checksum": "cd295ee735fe0fd2a8702978f20719f3", "baseChecksum": "9beedeb24025c057f2fd58a2e80153ec", "status": "translated" + }, + "ru": { + "checksum": "22b8692bfbcda0a1e43ca4521408a6cb", + "baseChecksum": "9beedeb24025c057f2fd58a2e80153ec", + "status": "translated" + }, + "ja": { + "checksum": "821d3a354e82dec319a31f7392352969", + "baseChecksum": "9beedeb24025c057f2fd58a2e80153ec", + "status": "translated" + }, + "de": { + "checksum": "208d41980a77ef52ffc6e00798e7bb38", + "baseChecksum": "9beedeb24025c057f2fd58a2e80153ec", + "status": "translated" } }, "createFirstFolder": { @@ -102,6 +192,21 @@ "checksum": "6dbbbf38d3d3d6ce8cc6eb844d606427", "baseChecksum": "07883be3c67d32d56eb1e86891f130ca", "status": "translated" + }, + "ru": { + "checksum": "65b1dd36c11ac5a40d271a0c9f24e964", + "baseChecksum": "07883be3c67d32d56eb1e86891f130ca", + "status": "translated" + }, + "ja": { + "checksum": "d7bbc4cde5e4080f2b18b38c261eb03d", + "baseChecksum": "07883be3c67d32d56eb1e86891f130ca", + "status": "translated" + }, + "de": { + "checksum": "dd82851ec9130cdff8bfe9612fe31bb9", + "baseChecksum": "07883be3c67d32d56eb1e86891f130ca", + "status": "translated" } }, "folderCreated": { @@ -117,6 +222,21 @@ "checksum": "163f36c9e2f540d418bcfdb38974dfc0", "baseChecksum": "a849da990cd1a54faca8b4923561fc60", "status": "translated" + }, + "ru": { + "checksum": "bf70d281db45c6bd47d2f85bbba6c854", + "baseChecksum": "a849da990cd1a54faca8b4923561fc60", + "status": "translated" + }, + "ja": { + "checksum": "251d9199ea2c2febe0c2464c333ef75c", + "baseChecksum": "a849da990cd1a54faca8b4923561fc60", + "status": "translated" + }, + "de": { + "checksum": "736c372fdf8f87e58841d882710839c9", + "baseChecksum": "a849da990cd1a54faca8b4923561fc60", + "status": "translated" } }, "folderAlreadyExists": { @@ -132,6 +252,21 @@ "checksum": "7644a84d1884b115c717bf5e59b5072b", "baseChecksum": "8f0c6e690f8fc7b4930fa26eea038fe6", "status": "translated" + }, + "ru": { + "checksum": "460636e13b11c535f44497a274ac16cb", + "baseChecksum": "8f0c6e690f8fc7b4930fa26eea038fe6", + "status": "translated" + }, + "ja": { + "checksum": "585693643f563620986e9fd5aa7ffae6", + "baseChecksum": "8f0c6e690f8fc7b4930fa26eea038fe6", + "status": "translated" + }, + "de": { + "checksum": "db0b86b7564861a2e1388ab232ac7c53", + "baseChecksum": "8f0c6e690f8fc7b4930fa26eea038fe6", + "status": "translated" } }, "createFolderFailed": { @@ -147,6 +282,21 @@ "checksum": "3a8006f316f0b8e692ca464c5c728c70", "baseChecksum": "398dff483997d01292f5848d5f78e409", "status": "translated" + }, + "ru": { + "checksum": "5c86bb3f4b6b381f42094b79f6e2ba62", + "baseChecksum": "398dff483997d01292f5848d5f78e409", + "status": "translated" + }, + "ja": { + "checksum": "653707d6996bec51f6bbd51b29d7aee7", + "baseChecksum": "398dff483997d01292f5848d5f78e409", + "status": "translated" + }, + "de": { + "checksum": "7cbd86dab907a1f49ee0fcf5ea2ac8e2", + "baseChecksum": "398dff483997d01292f5848d5f78e409", + "status": "translated" } }, "rootLabel": { @@ -162,6 +312,21 @@ "checksum": "29be74725a0760c1c05e11fa9de518e6", "baseChecksum": "63a9f0ea7bb98050796b649e85481845", "status": "translated" + }, + "ru": { + "checksum": "590f13873371c8324f9c1653ebb33b3c", + "baseChecksum": "63a9f0ea7bb98050796b649e85481845", + "status": "translated" + }, + "ja": { + "checksum": "99ef7b0d0959faa61bef232697dae9c4", + "baseChecksum": "63a9f0ea7bb98050796b649e85481845", + "status": "translated" + }, + "de": { + "checksum": "e93dde3aa767da911495697e4737808c", + "baseChecksum": "63a9f0ea7bb98050796b649e85481845", + "status": "translated" } }, "selectorAriaLabelX": { @@ -177,6 +342,21 @@ "checksum": "944c1bba8a4b6cdb6d462fa4cd6cab58", "baseChecksum": "b25b6c575d57b6fd62e0b80e20fe9c16", "status": "translated" + }, + "ru": { + "checksum": "d622603fd981f67772ec7f1bc7845ff3", + "baseChecksum": "b25b6c575d57b6fd62e0b80e20fe9c16", + "status": "translated" + }, + "ja": { + "checksum": "08175456a2012dc021d7a17f35b7f4e1", + "baseChecksum": "b25b6c575d57b6fd62e0b80e20fe9c16", + "status": "translated" + }, + "de": { + "checksum": "ed06c442f616d33752f32266cbe3b87c", + "baseChecksum": "b25b6c575d57b6fd62e0b80e20fe9c16", + "status": "translated" } }, "treeAriaLabel": { @@ -192,6 +372,21 @@ "checksum": "0046b816158dd1dd70458ce6b0b0dd9e", "baseChecksum": "3b3f435ac41d9af09975ca8fd7d9a957", "status": "translated" + }, + "ru": { + "checksum": "9c33ac0b6e28b319e2c6ac24de0e54b0", + "baseChecksum": "3b3f435ac41d9af09975ca8fd7d9a957", + "status": "translated" + }, + "ja": { + "checksum": "b000acc997070fce721426d6c3738ab0", + "baseChecksum": "3b3f435ac41d9af09975ca8fd7d9a957", + "status": "translated" + }, + "de": { + "checksum": "da791976a20149dc89ff1b47d8806103", + "baseChecksum": "3b3f435ac41d9af09975ca8fd7d9a957", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/folderTree/resource_entries.json b/apps/tracker/src/i18n/browser/folderTree/resource_entries.json index a030e776..94e405b4 100644 --- a/apps/tracker/src/i18n/browser/folderTree/resource_entries.json +++ b/apps/tracker/src/i18n/browser/folderTree/resource_entries.json @@ -4,34 +4,49 @@ "comment": "Aria-label for the folder search input in the folder tree sidebar", "tags": ["browser"], "es": "Filtrar carpetas", - "fr-ca": "dossiers de filtrage" + "fr-ca": "dossiers de filtrage", + "ru": "Фильтрация папок", + "ja": "フォルダーをフィルタリングする", + "de": "Filterordner" }, "showCurrentFolderTooltip": { "source": "Show only current folder", "comment": "Tooltip and aria-label for the toggle button to show only the current folder's resources", "tags": ["browser"], "es": "Mostrar solo la carpeta actual", - "fr-ca": "Afficher uniquement le dossier actuel" + "fr-ca": "Afficher uniquement le dossier actuel", + "ru": "Показать только текущую папку", + "ja": "現在のフォルダーのみを表示する", + "de": "Nur aktuellen Ordner anzeigen" }, "showNestedResourcesTooltip": { "source": "Show all nested resources", "comment": "Tooltip and aria-label for the toggle button to show all nested resources recursively", "tags": ["browser"], "es": "Mostrar todos los recursos anidados", - "fr-ca": "Afficher toutes les ressources imbriquées" + "fr-ca": "Afficher toutes les ressources imbriquées", + "ru": "Показать все вложенные ресурсы", + "ja": "ネストされたリソースをすべて表示する", + "de": "Alle verschachtelten Ressourcen anzeigen" }, "addFolderAriaLabel": { "source": "Add folder", "comment": "Aria-label for the add folder button in the folder tree", "tags": ["browser"], "es": "Agregar carpeta", - "fr-ca": "Ajouter un dossier" + "fr-ca": "Ajouter un dossier", + "ru": "Добавить папку", + "ja": "フォルダーを追加する", + "de": "Ordner hinzufügen" }, "addFolderTooltip": { "source": "Add folder (Ctrl+Shift+N)", "comment": "Tooltip for the add folder button, includes keyboard shortcut", "tags": ["browser"], "es": "Agregar carpeta (Ctrl+Shift+N)", - "fr-ca": "Ajouter un dossier (Ctrl+Maj+N)" + "fr-ca": "Ajouter un dossier (Ctrl+Maj+N)", + "ru": "Добавить папку (Ctrl+Shift+N)", + "ja": "フォルダを追加する(Ctrl+Shift+N)", + "de": "Ordner hinzufügen (Strg+Umschalt+N)" } } diff --git a/apps/tracker/src/i18n/browser/folderTree/tracker_meta.json b/apps/tracker/src/i18n/browser/folderTree/tracker_meta.json index 071753bb..288e0ab9 100644 --- a/apps/tracker/src/i18n/browser/folderTree/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/folderTree/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "155631a10eacdcd6d715db7ed8c28196", "baseChecksum": "8aad8def5c9f4c9233fafc03317b3755", "status": "translated" + }, + "ru": { + "checksum": "f57d9699734d8deab0bc3f9f0f060be3", + "baseChecksum": "8aad8def5c9f4c9233fafc03317b3755", + "status": "translated" + }, + "ja": { + "checksum": "fea11c950afd6ad47292eb99e4e40ed7", + "baseChecksum": "8aad8def5c9f4c9233fafc03317b3755", + "status": "translated" + }, + "de": { + "checksum": "81159931475d47403a3c30e03da0221b", + "baseChecksum": "8aad8def5c9f4c9233fafc03317b3755", + "status": "translated" } }, "showCurrentFolderTooltip": { @@ -27,6 +42,21 @@ "checksum": "de031154ace17104f7b3f283dfe398df", "baseChecksum": "8bb8f6d2cca4c79060a585c3066b12dd", "status": "translated" + }, + "ru": { + "checksum": "222cea24291a7d6423cfb9b054bd9e47", + "baseChecksum": "8bb8f6d2cca4c79060a585c3066b12dd", + "status": "translated" + }, + "ja": { + "checksum": "f090ff3a99674445f3d75beadfb801f0", + "baseChecksum": "8bb8f6d2cca4c79060a585c3066b12dd", + "status": "translated" + }, + "de": { + "checksum": "a90298a016d931b17270dc64006f7ebc", + "baseChecksum": "8bb8f6d2cca4c79060a585c3066b12dd", + "status": "translated" } }, "showNestedResourcesTooltip": { @@ -42,6 +72,21 @@ "checksum": "6d3f087cfbe8ddfbb48108e78bcd06d9", "baseChecksum": "ef700afb7c85765e3b5122911e9461f7", "status": "translated" + }, + "ru": { + "checksum": "1cf4cbf25a09e2c5d6c5726732ab6bf7", + "baseChecksum": "ef700afb7c85765e3b5122911e9461f7", + "status": "translated" + }, + "ja": { + "checksum": "20c2914867f9af50fb54675c28e8fc36", + "baseChecksum": "ef700afb7c85765e3b5122911e9461f7", + "status": "translated" + }, + "de": { + "checksum": "497a7310379f11b0de9dcd3db93b0bb7", + "baseChecksum": "ef700afb7c85765e3b5122911e9461f7", + "status": "translated" } }, "addFolderAriaLabel": { @@ -57,6 +102,21 @@ "checksum": "72b188201ce2984052b2d7c8b9945c60", "baseChecksum": "b60bc90c77f58812129670659f977dbe", "status": "translated" + }, + "ru": { + "checksum": "ffa55f40fbdf1182b30fc5247a1432c0", + "baseChecksum": "b60bc90c77f58812129670659f977dbe", + "status": "translated" + }, + "ja": { + "checksum": "3bfda665313f438a5c1f8b67a0a5f767", + "baseChecksum": "b60bc90c77f58812129670659f977dbe", + "status": "translated" + }, + "de": { + "checksum": "757c6630b15b67141e54ec209243c98d", + "baseChecksum": "b60bc90c77f58812129670659f977dbe", + "status": "translated" } }, "addFolderTooltip": { @@ -72,6 +132,21 @@ "checksum": "f92b21768583c08ddfde329bbe1b7d03", "baseChecksum": "79e6232f92f3cc7bd3d268f4ec3c9e95", "status": "translated" + }, + "ru": { + "checksum": "2395fc181f2131519801b06b85121cc8", + "baseChecksum": "79e6232f92f3cc7bd3d268f4ec3c9e95", + "status": "translated" + }, + "ja": { + "checksum": "dcc7e150442bdf9e0e99890e676d94ef", + "baseChecksum": "79e6232f92f3cc7bd3d268f4ec3c9e95", + "status": "translated" + }, + "de": { + "checksum": "5ee051c4d646523cd785f3ef77e05b5b", + "baseChecksum": "79e6232f92f3cc7bd3d268f4ec3c9e95", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/indexingOverlay/resource_entries.json b/apps/tracker/src/i18n/browser/indexingOverlay/resource_entries.json index ed92a120..756dccd2 100644 --- a/apps/tracker/src/i18n/browser/indexingOverlay/resource_entries.json +++ b/apps/tracker/src/i18n/browser/indexingOverlay/resource_entries.json @@ -4,20 +4,29 @@ "comment": "Message shown while the collection cache is being built", "tags": ["browser"], "es": "Colección de indexación...", - "fr-ca": "Collection d'indexation..." + "fr-ca": "Collection d'indexation...", + "ru": "Индексирование коллекции...", + "ja": "コレクションのインデックスを作成しています...", + "de": "Sammlung wird indexiert..." }, "errorTitle": { "source": "Indexing Failed", "comment": "Title of the error card shown when indexing fails", "tags": ["browser"], "es": "Error de indexación", - "fr-ca": "L'indexation a échoué" + "fr-ca": "L'indexation a échoué", + "ru": "Индексирование не удалось", + "ja": "インデックス作成に失敗しました", + "de": "Indizierung fehlgeschlagen" }, "defaultError": { "source": "An error occurred while indexing the collection.", "comment": "Default error message shown in the indexing overlay when no specific error is available", "tags": ["browser"], "es": "Se produjo un error al indexar la colección.", - "fr-ca": "Une erreur s'est produite lors de l'indexation de la collection." + "fr-ca": "Une erreur s'est produite lors de l'indexation de la collection.", + "ru": "Произошла ошибка при индексировании коллекции.", + "ja": "コレクションのインデックス作成中にエラーが発生しました。", + "de": "Beim Indizieren der Sammlung ist ein Fehler aufgetreten." } } diff --git a/apps/tracker/src/i18n/browser/indexingOverlay/tracker_meta.json b/apps/tracker/src/i18n/browser/indexingOverlay/tracker_meta.json index fd09b0fd..374d4d3b 100644 --- a/apps/tracker/src/i18n/browser/indexingOverlay/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/indexingOverlay/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "2a184dd464b0f6a7199e01d15f1f185b", "baseChecksum": "a9dd11b1c5a6d656bbc67f69b58303ee", "status": "translated" + }, + "ru": { + "checksum": "e6be89a9e89333c4134ca0260c94b521", + "baseChecksum": "a9dd11b1c5a6d656bbc67f69b58303ee", + "status": "translated" + }, + "ja": { + "checksum": "27a2ccde5f10886237423e9be9e0678e", + "baseChecksum": "a9dd11b1c5a6d656bbc67f69b58303ee", + "status": "translated" + }, + "de": { + "checksum": "586bd6ec222b562ecc450b849631d530", + "baseChecksum": "a9dd11b1c5a6d656bbc67f69b58303ee", + "status": "translated" } }, "errorTitle": { @@ -27,6 +42,21 @@ "checksum": "ec2254857a194f7e76c7ac5d14e7337c", "baseChecksum": "bdb612b5237ec3727393283341b07e0e", "status": "translated" + }, + "ru": { + "checksum": "668e2616a7e2ad25f5c5414c3232adbb", + "baseChecksum": "bdb612b5237ec3727393283341b07e0e", + "status": "translated" + }, + "ja": { + "checksum": "16d3d677155ea8fe7712686c7b2c8e63", + "baseChecksum": "bdb612b5237ec3727393283341b07e0e", + "status": "translated" + }, + "de": { + "checksum": "15e8d96912feb77accd22ff28a226d71", + "baseChecksum": "bdb612b5237ec3727393283341b07e0e", + "status": "translated" } }, "defaultError": { @@ -42,6 +72,21 @@ "checksum": "d1352f09b538c934478dc5f0050c8b0d", "baseChecksum": "cb1fe5c48be070cca575c0c84b89c06d", "status": "translated" + }, + "ru": { + "checksum": "15092bbfb45097e6177acd73307896f3", + "baseChecksum": "cb1fe5c48be070cca575c0c84b89c06d", + "status": "translated" + }, + "ja": { + "checksum": "1b735119013f84e4351bafbcbc6c79a4", + "baseChecksum": "cb1fe5c48be070cca575c0c84b89c06d", + "status": "translated" + }, + "de": { + "checksum": "89c65aa4db8801082d9d6a239e9a0db0", + "baseChecksum": "cb1fe5c48be070cca575c0c84b89c06d", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/localeFilter/resource_entries.json b/apps/tracker/src/i18n/browser/localeFilter/resource_entries.json index 7030375b..1cd240af 100644 --- a/apps/tracker/src/i18n/browser/localeFilter/resource_entries.json +++ b/apps/tracker/src/i18n/browser/localeFilter/resource_entries.json @@ -4,6 +4,9 @@ "comment": "Aria-label for the locale filter button. { text } is the current filter display text (e.g. 'All' or a locale code)", "tags": ["browser"], "es": "Filtrar regiones. Actualmente se muestra: {texto}", - "fr-ca": "Filtrer les paramètres régionaux. Affichage actuel : { texte }" + "fr-ca": "Filtrer les paramètres régionaux. Affichage actuel : { texte }", + "ru": "Фильтр по языкам. В данный момент отображается: { текст }", + "ja": "地域をフィルタリングします。現在表示中: { テキスト }", + "de": "Gebietsschemas filtern. Aktuell angezeigt: { text }" } } diff --git a/apps/tracker/src/i18n/browser/localeFilter/tracker_meta.json b/apps/tracker/src/i18n/browser/localeFilter/tracker_meta.json index d8ffd773..fb7dc4fd 100644 --- a/apps/tracker/src/i18n/browser/localeFilter/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/localeFilter/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "ac4c82f234ba7f6fb0ac78e8d8dc395b", "baseChecksum": "8a99d337e7d73673d6afcfa72e7b82fd", "status": "translated" + }, + "ru": { + "checksum": "d44d30a0dbadd7dbcaebfe9f596e7a6a", + "baseChecksum": "8a99d337e7d73673d6afcfa72e7b82fd", + "status": "translated" + }, + "ja": { + "checksum": "a9125be4e99103ed768fb2f81ed360ed", + "baseChecksum": "8a99d337e7d73673d6afcfa72e7b82fd", + "status": "translated" + }, + "de": { + "checksum": "c5e13cfa1c8c71a572983efde4e55482", + "baseChecksum": "8a99d337e7d73673d6afcfa72e7b82fd", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/placeholder/resource_entries.json b/apps/tracker/src/i18n/browser/placeholder/resource_entries.json index 8a9c6096..4e51df1d 100644 --- a/apps/tracker/src/i18n/browser/placeholder/resource_entries.json +++ b/apps/tracker/src/i18n/browser/placeholder/resource_entries.json @@ -3,18 +3,27 @@ "source": "Translation Browser Coming Soon", "comment": "Placeholder title for browser feature", "es": "Navegador de traducción disponible próximamente", - "fr-ca": "Navigateur de traduction bientôt disponible" + "fr-ca": "Navigateur de traduction bientôt disponible", + "ru": "Браузер для перевода скоро появится.", + "ja": "翻訳ブラウザ近日公開予定", + "de": "Übersetzungsbrowser demnächst verfügbar" }, "message": { "source": "The translation browser feature is currently under development. Soon you'll be able to view, edit, and manage all translations within this collection.", "comment": "Placeholder message explaining feature status", "es": "La función de búsqueda de traducciones está en desarrollo. Pronto podrás ver, editar y gestionar todas las traducciones de esta colección.", - "fr-ca": "La fonctionnalité du navigateur de traductions est en cours de développement. Vous pourrez bientôt consulter, modifier et gérer toutes les traductions de cette collection." + "fr-ca": "La fonctionnalité du navigateur de traductions est en cours de développement. Vous pourrez bientôt consulter, modifier et gérer toutes les traductions de cette collection.", + "ru": "Функция просмотра переводов в настоящее время находится в разработке. Вскоре вы сможете просматривать, редактировать и управлять всеми переводами в этой коллекции.", + "ja": "翻訳ブラウザ機能は現在開発中です。まもなく、このコレクション内のすべての翻訳を表示、編集、管理できるようになります。", + "de": "Die Übersetzungsbrowser-Funktion befindet sich derzeit in der Entwicklung. In Kürze können Sie alle Übersetzungen dieser Sammlung anzeigen, bearbeiten und verwalten." }, "collection": { "source": "Collection", "comment": "Label for collection name display", "es": "Recopilación", - "fr-ca": "Collection" + "fr-ca": "Collection", + "ru": "Коллекция", + "ja": "コレクション", + "de": "Sammlung" } } diff --git a/apps/tracker/src/i18n/browser/placeholder/tracker_meta.json b/apps/tracker/src/i18n/browser/placeholder/tracker_meta.json index db00838f..c83e3541 100644 --- a/apps/tracker/src/i18n/browser/placeholder/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/placeholder/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "531e79f4739df35a25f6ebd479c2aa67", "baseChecksum": "c7c796f3d37ab9fbc712335f9def7b81", "status": "translated" + }, + "ru": { + "checksum": "e66e399449da382ed3c954e8f5e4a915", + "baseChecksum": "c7c796f3d37ab9fbc712335f9def7b81", + "status": "translated" + }, + "ja": { + "checksum": "5e7cd0c3a357e01a8377e570c101d36b", + "baseChecksum": "c7c796f3d37ab9fbc712335f9def7b81", + "status": "translated" + }, + "de": { + "checksum": "c030d07060ea8ea8173302e3042e375d", + "baseChecksum": "c7c796f3d37ab9fbc712335f9def7b81", + "status": "translated" } }, "message": { @@ -27,6 +42,21 @@ "checksum": "8fbb0a3a0e5c526770762bb6c09da9ce", "baseChecksum": "1cf7c14142897e3c49ea7b6b28ceb567", "status": "translated" + }, + "ru": { + "checksum": "506d3a73c9cb4d2a7d596359925ddc26", + "baseChecksum": "1cf7c14142897e3c49ea7b6b28ceb567", + "status": "translated" + }, + "ja": { + "checksum": "d028883676b3802bd56b4fc3a1bcb523", + "baseChecksum": "1cf7c14142897e3c49ea7b6b28ceb567", + "status": "translated" + }, + "de": { + "checksum": "b27b43a4af8a50725701f3e2ccc04e38", + "baseChecksum": "1cf7c14142897e3c49ea7b6b28ceb567", + "status": "translated" } }, "collection": { @@ -42,6 +72,21 @@ "checksum": "d15b505cce09406de9f918cb1f8c641c", "baseChecksum": "d15b505cce09406de9f918cb1f8c641c", "status": "translated" + }, + "ru": { + "checksum": "e383e52780ab039fa602807bc784b3ac", + "baseChecksum": "d15b505cce09406de9f918cb1f8c641c", + "status": "translated" + }, + "ja": { + "checksum": "695b82464aee401b828677a0100f6cba", + "baseChecksum": "d15b505cce09406de9f918cb1f8c641c", + "status": "translated" + }, + "de": { + "checksum": "475b422743f9887f4d8bd4974b28b499", + "baseChecksum": "d15b505cce09406de9f918cb1f8c641c", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/resource_entries.json b/apps/tracker/src/i18n/browser/resource_entries.json index b29df8b8..8c81421a 100644 --- a/apps/tracker/src/i18n/browser/resource_entries.json +++ b/apps/tracker/src/i18n/browser/resource_entries.json @@ -3,140 +3,209 @@ "source": "Back to collections", "comment": "Aria-label for back button in browser", "es": "Volver a las colecciones", - "fr-ca": "Retour aux collections" + "fr-ca": "Retour aux collections", + "ru": "Вернуться к коллекциям", + "ja": "コレクション一覧に戻る", + "de": "Zurück zu den Sammlungen" }, "filterFolders": { "source": "Filter folders...", "comment": "Placeholder text in a filter input that filters a list of folders", "es": "Filtrar carpetas...", - "fr-ca": "Dossiers de filtrage..." + "fr-ca": "Dossiers de filtrage...", + "ru": "Фильтрация папок...", + "ja": "フォルダをフィルタリング...", + "de": "Filterordner..." }, "loadingFolders": { "source": "Loading folders...", "es": "Cargando carpetas...", - "fr-ca": "Chargement des dossiers..." + "fr-ca": "Chargement des dossiers...", + "ru": "Загрузка папок...", + "ja": "フォルダを読み込んでいます...", + "de": "Ordner werden geladen..." }, "noFoldersMatchSearch": { "source": "No folders match your search", "es": "No se encontraron carpetas que coincidan con su búsqueda.", - "fr-ca": "Aucun dossier ne correspond à votre recherche" + "fr-ca": "Aucun dossier ne correspond à votre recherche", + "ru": "Папки не соответствуют вашему запросу.", + "ja": "検索条件に一致するフォルダはありません", + "de": "Keine Ordner entsprechen Ihrer Suche" }, "noFoldersFound": { "source": "No folders found", "es": "No se encontraron carpetas", - "fr-ca": "Aucun dossier trouvé" + "fr-ca": "Aucun dossier trouvé", + "ru": "Папки не найдены", + "ja": "フォルダが見つかりませんでした", + "de": "Keine Ordner gefunden" }, "clickToLoad": { "source": "click to load", "comment": "Message shown to user on a hierarchy item that is not loaded yet from the backend", "es": "Haz clic para cargar", - "fr-ca": "cliquer pour charger" + "fr-ca": "cliquer pour charger", + "ru": "нажмите для загрузки", + "ja": "クリックして読み込む", + "de": "Zum Laden klicken" }, "loadingCollectionConfiguration": { "source": "Loading collection configuration...", "es": "Cargando configuración de la colección...", - "fr-ca": "Chargement de la configuration de la collection..." + "fr-ca": "Chargement de la configuration de la collection...", + "ru": "Загрузка конфигурации коллекции...", + "ja": "コレクション設定を読み込んでいます...", + "de": "Sammlungskonfiguration wird geladen..." }, "loadingTranslations": { "source": "Loading translations...", "es": "Cargando traducciones...", - "fr-ca": "Chargement des traductions..." + "fr-ca": "Chargement des traductions...", + "ru": "Загрузка переводов...", + "ja": "翻訳を読み込んでいます...", + "de": "Übersetzungen werden geladen..." }, "noTranslationsFoundInFolder": { "source": "No translations found in this folder.", "es": "No se encontraron traducciones en esta carpeta.", - "fr-ca": "Aucune traduction trouvée dans ce dossier." + "fr-ca": "Aucune traduction trouvée dans ce dossier.", + "ru": "В этой папке не найдено ни одного перевода.", + "ja": "このフォルダには翻訳ファイルが見つかりませんでした。", + "de": "In diesem Ordner wurden keine Übersetzungen gefunden." }, "searchTranslations": { "source": "Search (min 3 characters)...", "es": "Buscar (mínimo 3 caracteres)...", - "fr-ca": "Recherche (3 caractères minimum)..." + "fr-ca": "Recherche (3 caractères minimum)...", + "ru": "Поиск (минимум 3 символа)...", + "ja": "検索(最低3文字)...", + "de": "Suche (mind. 3 Zeichen)..." }, "showingSearchResultsForX": { "source": "Showing search results for \"{query}\"", "es": "Mostrando resultados de búsqueda para \"{query}\"", - "fr-ca": "Affichage des résultats de recherche pour \"{query}\"" + "fr-ca": "Affichage des résultats de recherche pour \"{query}\"", + "ru": "Показаны результаты поиска по запросу \"{query}\"", + "ja": "「{query}」の検索結果を表示しています。", + "de": "Suchergebnisse für \"{query}\" anzeigen" }, "clearSearch": { "source": "Clear Search", "es": "Búsqueda clara", - "fr-ca": "Effacer la recherche" + "fr-ca": "Effacer la recherche", + "ru": "Очистить поиск", + "ja": "検索をクリア", + "de": "Suche löschen" }, "noFolderSelected": { "source": "No resource folder selected", "comment": "Breadcrumb empty state when no folder is selected", "tags": ["browser"], "es": "No se seleccionó ninguna carpeta de recursos", - "fr-ca": "Aucun dossier de ressources sélectionné" + "fr-ca": "Aucun dossier de ressources sélectionné", + "ru": "Папка ресурсов не выбрана", + "ja": "リソースフォルダが選択されていません", + "de": "Kein Ressourcenordner ausgewählt" }, "addTranslationButton": { "source": "Add Translation", "comment": "Button text to add a new translation", "tags": ["browser"], "es": "Añadir traducción", - "fr-ca": "Ajouter une traduction" + "fr-ca": "Ajouter une traduction", + "ru": "Добавить перевод", + "ja": "翻訳を追加", + "de": "Übersetzung hinzufügen" }, "sortAscending": { "source": "Sort ascending", "comment": "Aria-label for sort ascending button", "tags": ["browser"], "es": "Ordenar ascendentemente", - "fr-ca": "Trier en ordre croissant" + "fr-ca": "Trier en ordre croissant", + "ru": "Сортировка по возрастанию", + "ja": "昇順で並べ替え", + "de": "Aufsteigend sortieren" }, "sortDescending": { "source": "Sort descending", "comment": "Aria-label for sort descending button", "tags": ["browser"], "es": "Ordenar descendentemente", - "fr-ca": "Trier par ordre décroissant" + "fr-ca": "Trier par ordre décroissant", + "ru": "Сортировать по убыванию", + "ja": "降順で並べ替え", + "de": "Sortieren Sie absteigend" }, "sortAscendingTooltip": { "source": "Sort ascending (A→Z)", "comment": "Tooltip for sort ascending button", "tags": ["browser"], "es": "Ordenar ascendentemente (A→Z)", - "fr-ca": "Trier par ordre croissant (A→Z)" + "fr-ca": "Trier par ordre croissant (A→Z)", + "ru": "Сортировка по возрастанию (от А до Я)", + "ja": "昇順(A→Z)に並べ替え", + "de": "Aufsteigend sortieren (A→Z)" }, "sortDescendingTooltip": { "source": "Sort descending (Z→A)", "comment": "Tooltip for sort descending button", "tags": ["browser"], "es": "Ordenar descendentemente (Z→A)", - "fr-ca": "Trier par ordre décroissant (Z→A)" + "fr-ca": "Trier par ordre décroissant (Z→A)", + "ru": "Сортировка по убыванию (Z→A)", + "ja": "降順でソート(Z→A)", + "de": "Sortieren absteigend (Z→A)" }, "selectFolderFirst": { "source": "Select a folder first", "comment": "Tooltip shown on Add Translation button when no folder is selected", "tags": ["browser"], "es": "Seleccione una carpeta primero", - "fr-ca": "Sélectionnez d'abord un dossier" + "fr-ca": "Sélectionnez d'abord un dossier", + "ru": "Сначала выберите папку.", + "ja": "まずフォルダを選択してください。", + "de": "Wählen Sie zuerst einen Ordner aus." }, "addNewTranslationTooltip": { "source": "Add a new translation", "comment": "Tooltip shown on Add Translation button when a folder is selected", "tags": ["browser"], "es": "Añadir una nueva traducción", - "fr-ca": "Ajouter une nouvelle traduction" + "fr-ca": "Ajouter une nouvelle traduction", + "ru": "Добавить новый перевод", + "ja": "新しい翻訳を追加する", + "de": "Füge eine neue Übersetzung hinzu" }, "noTranslation": { "source": "No translation", "comment": "Placeholder when a translation value is empty", "tags": ["browser"], "es": "Sin traducción", - "fr-ca": "Aucune traduction" + "fr-ca": "Aucune traduction", + "ru": "Нет перевода", + "ja": "翻訳なし", + "de": "Keine Übersetzung" }, "commentPrefix": { "source": "Comment:", "comment": "Label prefix before a comment text", "tags": ["browser"], "es": "Comentario:", - "fr-ca": "Commentaire:" + "fr-ca": "Commentaire:", + "ru": "Комментарий:", + "ja": "コメント:", + "de": "Kommentar:" }, "toggleExpansion": { "source": "Toggle expansion", "comment": "Aria-label for the expand/collapse button on a translation item", "tags": ["browser"], "es": "Activar o desactivar la expansión", - "fr-ca": "Basculer l'extension" + "fr-ca": "Basculer l'extension", + "ru": "Переключить расширение", + "ja": "展開を切り替える", + "de": "Erweiterung umschalten" } } diff --git a/apps/tracker/src/i18n/browser/similarTranslations/resource_entries.json b/apps/tracker/src/i18n/browser/similarTranslations/resource_entries.json index 60e64dcd..dab1b7c5 100644 --- a/apps/tracker/src/i18n/browser/similarTranslations/resource_entries.json +++ b/apps/tracker/src/i18n/browser/similarTranslations/resource_entries.json @@ -4,34 +4,49 @@ "comment": "Header title for similar translations panel", "tags": ["browser"], "es": "Traducciones similares", - "fr-ca": "Traductions similaires" + "fr-ca": "Traductions similaires", + "ru": "Похожие переводы", + "ja": "類似の翻訳", + "de": "Ähnliche Übersetzungen" }, "idle": { "source": "Similar translations will appear as you type", "comment": "Message shown when no search query entered yet", "tags": ["browser"], "es": "Aparecerán traducciones similares a medida que escribas.", - "fr-ca": "Des traductions semblables apparaîtront au fur et à mesure que vous taperez." + "fr-ca": "Des traductions semblables apparaîtront au fur et à mesure que vous taperez.", + "ru": "Похожие переводы будут появляться по мере ввода текста.", + "ja": "入力すると類似の翻訳が表示されます", + "de": "Ähnliche Übersetzungen werden während der Eingabe angezeigt." }, "loading": { "source": "Searching for similar translations...", "comment": "Loading message while searching for similar translations", "tags": ["browser"], "es": "Buscando traducciones similares...", - "fr-ca": "Recherche de traductions similaires..." + "fr-ca": "Recherche de traductions similaires...", + "ru": "Ищу похожие переводы...", + "ja": "類似の翻訳を検索中...", + "de": "Suche nach ähnlichen Übersetzungen..." }, "empty": { "source": "No similar translations found", "comment": "Message when search returns no results", "tags": ["browser"], "es": "No se encontraron traducciones similares", - "fr-ca": "Aucune traduction semblable trouvée" + "fr-ca": "Aucune traduction semblable trouvée", + "ru": "Похожие переводы не найдены", + "ja": "類似の翻訳は見つかりませんでした", + "de": "Keine ähnlichen Übersetzungen gefunden" }, "showMoreX": { "source": "Show {count} more", "comment": "Button to show remaining similar translation results, count is the number of hidden results", "tags": ["browser"], "es": "Mostrar {count} más", - "fr-ca": "Show {count} more" + "fr-ca": "Show {count} more", + "ru": "Показать {count} больше", + "ja": "{count} を表示", + "de": "Mehr anzeigen {count}" } } diff --git a/apps/tracker/src/i18n/browser/similarTranslations/tracker_meta.json b/apps/tracker/src/i18n/browser/similarTranslations/tracker_meta.json index 840cc2ae..15460e94 100644 --- a/apps/tracker/src/i18n/browser/similarTranslations/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/similarTranslations/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "ff906b3e968bf0ca20cb9bffc71ba0a7", "baseChecksum": "fdf7dc519363415a82c0e19d15661480", "status": "translated" + }, + "ru": { + "checksum": "629d4cce6035f21e2325986627891758", + "baseChecksum": "fdf7dc519363415a82c0e19d15661480", + "status": "translated" + }, + "ja": { + "checksum": "eb97498a7f0cecf1062b1b0e7e1f1e8f", + "baseChecksum": "fdf7dc519363415a82c0e19d15661480", + "status": "translated" + }, + "de": { + "checksum": "8ffa51bfa4e1f850fb1468d1d15331ad", + "baseChecksum": "fdf7dc519363415a82c0e19d15661480", + "status": "translated" } }, "idle": { @@ -27,6 +42,21 @@ "checksum": "44b95b68f10286428c104922a11d1909", "baseChecksum": "fc1752e501589956925c6d7ec51b4737", "status": "translated" + }, + "ru": { + "checksum": "49f3d721c042bb712edd44ab31254825", + "baseChecksum": "fc1752e501589956925c6d7ec51b4737", + "status": "translated" + }, + "ja": { + "checksum": "fb9debff3b7b68b88e0b061292bb8567", + "baseChecksum": "fc1752e501589956925c6d7ec51b4737", + "status": "translated" + }, + "de": { + "checksum": "e36150dc69270c14c38d3eb8e9909138", + "baseChecksum": "fc1752e501589956925c6d7ec51b4737", + "status": "translated" } }, "loading": { @@ -42,6 +72,21 @@ "checksum": "fcf85f1ec4d1f574ea2a1a5687dc8f10", "baseChecksum": "1c5c437ca05fa28416068fd6f05809e6", "status": "translated" + }, + "ru": { + "checksum": "0c9e8dbe3c7bee3c1564d9beafcbf6bc", + "baseChecksum": "1c5c437ca05fa28416068fd6f05809e6", + "status": "translated" + }, + "ja": { + "checksum": "e8a3a290283e520f5d3f6a399422ac01", + "baseChecksum": "1c5c437ca05fa28416068fd6f05809e6", + "status": "translated" + }, + "de": { + "checksum": "2b994a8f82efde93a1f36f51b31f4d68", + "baseChecksum": "1c5c437ca05fa28416068fd6f05809e6", + "status": "translated" } }, "empty": { @@ -57,6 +102,21 @@ "checksum": "aa117d0c03a1cc44ee64639f87971072", "baseChecksum": "fd7e0754b18f70245696cdee0be0ab26", "status": "translated" + }, + "ru": { + "checksum": "153764e3ac7828a26b9e80f7a3612530", + "baseChecksum": "fd7e0754b18f70245696cdee0be0ab26", + "status": "translated" + }, + "ja": { + "checksum": "cefdcff170cce639ea0ba9c6ad5b4ea1", + "baseChecksum": "fd7e0754b18f70245696cdee0be0ab26", + "status": "translated" + }, + "de": { + "checksum": "fa57d088b5a8546f06ded68e78a53c4b", + "baseChecksum": "fd7e0754b18f70245696cdee0be0ab26", + "status": "translated" } }, "showMoreX": { @@ -72,6 +132,21 @@ "checksum": "b39ae93853f9b177650ca742f758312d", "baseChecksum": "b39ae93853f9b177650ca742f758312d", "status": "new" + }, + "ru": { + "checksum": "ed667cad5e2af69efc1eca00c60429b8", + "baseChecksum": "b39ae93853f9b177650ca742f758312d", + "status": "translated" + }, + "ja": { + "checksum": "1a3b363e63a99737336b9f0bcca01221", + "baseChecksum": "b39ae93853f9b177650ca742f758312d", + "status": "translated" + }, + "de": { + "checksum": "590a948074ca10fae48086e64291db05", + "baseChecksum": "b39ae93853f9b177650ca742f758312d", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/status/resource_entries.json b/apps/tracker/src/i18n/browser/status/resource_entries.json index e586490c..66a9803d 100644 --- a/apps/tracker/src/i18n/browser/status/resource_entries.json +++ b/apps/tracker/src/i18n/browser/status/resource_entries.json @@ -4,27 +4,39 @@ "comment": "Translation status label: new, not yet translated", "tags": ["browser"], "es": "Nuevo", - "fr-ca": "Nouveau" + "fr-ca": "Nouveau", + "ru": "Новый", + "ja": "新しい", + "de": "Neu" }, "stale": { "source": "Stale", "comment": "Translation status label: source has changed and translation is outdated", "tags": ["browser"], "es": "Duro", - "fr-ca": "Vicié" + "fr-ca": "Vicié", + "ru": "Залежалый", + "ja": "古くなった", + "de": "Abgestanden" }, "translated": { "source": "Translated", "comment": "Translation status label: translated but not yet verified", "tags": ["browser"], "es": "Traducido", - "fr-ca": "Traduit" + "fr-ca": "Traduit", + "ru": "Переведено", + "ja": "翻訳済み", + "de": "Übersetzt" }, "verified": { "source": "Verified", "comment": "Translation status label: reviewed and approved", "tags": ["browser"], "es": "Verificado", - "fr-ca": "Vérifié" + "fr-ca": "Vérifié", + "ru": "Подтверждено", + "ja": "検証済み", + "de": "Bestätigt" } } diff --git a/apps/tracker/src/i18n/browser/status/tracker_meta.json b/apps/tracker/src/i18n/browser/status/tracker_meta.json index d7e10d14..a08a35a4 100644 --- a/apps/tracker/src/i18n/browser/status/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/status/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "9ea17b10f506b881fed906aab0a50f8d", "baseChecksum": "03c2e7e41ffc181a4e84080b4710e81e", "status": "translated" + }, + "ru": { + "checksum": "97ae6e0bca16b37dbdc5e324d0ecaf60", + "baseChecksum": "03c2e7e41ffc181a4e84080b4710e81e", + "status": "translated" + }, + "ja": { + "checksum": "ad4b0bd55882d4f7164630d4158d3c39", + "baseChecksum": "03c2e7e41ffc181a4e84080b4710e81e", + "status": "translated" + }, + "de": { + "checksum": "e85a2f1d6de3e3b0e71b1a2e19952659", + "baseChecksum": "03c2e7e41ffc181a4e84080b4710e81e", + "status": "translated" } }, "stale": { @@ -27,6 +42,21 @@ "checksum": "3ae88690725fe012389643e0056634b6", "baseChecksum": "f1ac273d3c6d8e6489bf332819a2f650", "status": "translated" + }, + "ru": { + "checksum": "0fa45772724dbd2cf9e99b15e04d7efa", + "baseChecksum": "f1ac273d3c6d8e6489bf332819a2f650", + "status": "translated" + }, + "ja": { + "checksum": "1720f89d6728615fff1b1d0bd2baf6fa", + "baseChecksum": "f1ac273d3c6d8e6489bf332819a2f650", + "status": "translated" + }, + "de": { + "checksum": "e47ee5c96bf1921b48a43365b499d6dc", + "baseChecksum": "f1ac273d3c6d8e6489bf332819a2f650", + "status": "translated" } }, "translated": { @@ -42,6 +72,21 @@ "checksum": "a1ed4f81da1f1862174ed8ef5cd3a279", "baseChecksum": "532220dbf680ea98d665427b145e72ca", "status": "translated" + }, + "ru": { + "checksum": "abcbcb3b8d5c0f82b5129dc554ffe62e", + "baseChecksum": "532220dbf680ea98d665427b145e72ca", + "status": "translated" + }, + "ja": { + "checksum": "6ccccd1019356b7c3d14daebbbc5c507", + "baseChecksum": "532220dbf680ea98d665427b145e72ca", + "status": "translated" + }, + "de": { + "checksum": "7f6819238f2dea34fd49f01d3740dbb6", + "baseChecksum": "532220dbf680ea98d665427b145e72ca", + "status": "translated" } }, "verified": { @@ -57,6 +102,21 @@ "checksum": "f180a2dcfad57fa4f4955babdc4c13ec", "baseChecksum": "3f68e67dc6c397aaa9d1c24c356f754f", "status": "translated" + }, + "ru": { + "checksum": "fe630d9925eeab434088f5ec6439fb33", + "baseChecksum": "3f68e67dc6c397aaa9d1c24c356f754f", + "status": "translated" + }, + "ja": { + "checksum": "56bde30703e7f2b67f711269f4596632", + "baseChecksum": "3f68e67dc6c397aaa9d1c24c356f754f", + "status": "translated" + }, + "de": { + "checksum": "ca339a1aaec8f339751c4c996bc4be34", + "baseChecksum": "3f68e67dc6c397aaa9d1c24c356f754f", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/statusFilter/resource_entries.json b/apps/tracker/src/i18n/browser/statusFilter/resource_entries.json index 60c068bc..4731b7e8 100644 --- a/apps/tracker/src/i18n/browser/statusFilter/resource_entries.json +++ b/apps/tracker/src/i18n/browser/statusFilter/resource_entries.json @@ -4,13 +4,19 @@ "comment": "Quick filter button that selects new and stale statuses", "tags": ["browser"], "es": "Necesita trabajo", - "fr-ca": "Nécessite des travaux" + "fr-ca": "Nécessite des travaux", + "ru": "Требуется доработка", + "ja": "改善が必要", + "de": "Überarbeitungsbedürftig" }, "ariaLabelX": { "source": "Filter by status. Currently showing: { text }", "comment": "Aria-label for the status filter button. { text } is the current filter display text (e.g. 'All' or status name)", "tags": ["browser"], "es": "Filtrar por estado. Actualmente se muestra: {texto}", - "fr-ca": "Filtrer par statut. Affichage actuel : { texte }" + "fr-ca": "Filtrer par statut. Affichage actuel : { texte }", + "ru": "Фильтр по статусу. В данный момент отображается: { текст }", + "ja": "ステータスで絞り込み。現在表示中:{テキスト}", + "de": "Nach Status filtern. Aktuell angezeigt: { text }" } } diff --git a/apps/tracker/src/i18n/browser/statusFilter/tracker_meta.json b/apps/tracker/src/i18n/browser/statusFilter/tracker_meta.json index 10d85696..9be19988 100644 --- a/apps/tracker/src/i18n/browser/statusFilter/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/statusFilter/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "3c388b094f2f1d561d99a41462f02279", "baseChecksum": "82198ade859bc9f4034a6dd31276d473", "status": "translated" + }, + "ru": { + "checksum": "58291dae413e4204dd1dc0adb831c6a7", + "baseChecksum": "82198ade859bc9f4034a6dd31276d473", + "status": "translated" + }, + "ja": { + "checksum": "8b5d48d121784c6c800b9e719ea02926", + "baseChecksum": "82198ade859bc9f4034a6dd31276d473", + "status": "translated" + }, + "de": { + "checksum": "4820f28cfac23b34516fe45ed518dcf1", + "baseChecksum": "82198ade859bc9f4034a6dd31276d473", + "status": "translated" } }, "ariaLabelX": { @@ -27,6 +42,21 @@ "checksum": "ba99ae2f5ef8f8da0cf7140ab17fc4ee", "baseChecksum": "dae9b86c4a9710ce0da801e65751954d", "status": "translated" + }, + "ru": { + "checksum": "046b8a36af662a632097d5e0ae2611ac", + "baseChecksum": "dae9b86c4a9710ce0da801e65751954d", + "status": "translated" + }, + "ja": { + "checksum": "ecf1e9344fc9256c2f55bc99d58b833d", + "baseChecksum": "dae9b86c4a9710ce0da801e65751954d", + "status": "translated" + }, + "de": { + "checksum": "a3e08e86453dc105c7c4d0db9fa0dbc3", + "baseChecksum": "dae9b86c4a9710ce0da801e65751954d", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/toast/resource_entries.json b/apps/tracker/src/i18n/browser/toast/resource_entries.json index 12efc703..e130c528 100644 --- a/apps/tracker/src/i18n/browser/toast/resource_entries.json +++ b/apps/tracker/src/i18n/browser/toast/resource_entries.json @@ -4,174 +4,249 @@ "comment": "Snackbar message after copying a key to clipboard", "tags": ["browser"], "es": "Copiado al portapapeles", - "fr-ca": "Copié dans le presse-papiers" + "fr-ca": "Copié dans le presse-papiers", + "ru": "Скопировано в буфер обмена", + "ja": "クリップボードにコピーされました", + "de": "In die Zwischenablage kopiert" }, "copyFailed": { "source": "Failed to copy", "comment": "Snackbar error message when clipboard copy fails", "tags": ["browser"], "es": "No se pudo copiar", - "fr-ca": "Échec de la copie" + "fr-ca": "Échec de la copie", + "ru": "Не удалось скопировать", + "ja": "コピーに失敗しました", + "de": "Kopiervorgang fehlgeschlagen" }, "resourceDeleted": { "source": "Resource deleted successfully", "comment": "Snackbar message after successfully deleting a resource", "tags": ["browser"], "es": "Recurso eliminado exitosamente", - "fr-ca": "Ressource supprimée avec succès" + "fr-ca": "Ressource supprimée avec succès", + "ru": "Ресурс успешно удален", + "ja": "リソースは正常に削除されました", + "de": "Ressource erfolgreich gelöscht" }, "deleteFailed": { "source": "Failed to delete resource", "comment": "Snackbar error message when resource deletion fails", "tags": ["browser"], "es": "No se pudo eliminar el recurso", - "fr-ca": "Échec de la suppression de la ressource" + "fr-ca": "Échec de la suppression de la ressource", + "ru": "Не удалось удалить ресурс", + "ja": "リソースの削除に失敗しました", + "de": "Ressource konnte nicht gelöscht werden" }, "translateFailed": { "source": "Failed to auto-translate resource", "comment": "Snackbar error message when auto-translation fails", "tags": ["browser"], "es": "No se pudo traducir automáticamente el recurso", - "fr-ca": "Échec de la traduction automatique de la ressource" + "fr-ca": "Échec de la traduction automatique de la ressource", + "ru": "Не удалось выполнить автоматический перевод ресурса.", + "ja": "リソースの自動翻訳に失敗しました", + "de": "Die automatische Übersetzung der Ressource ist fehlgeschlagen." }, "translationUpdated": { "source": "Translation updated successfully", "comment": "Snackbar message after successfully updating a translation", "tags": ["browser"], "es": "Traducción actualizada exitosamente", - "fr-ca": "Traduction mise à jour avec succès" + "fr-ca": "Traduction mise à jour avec succès", + "ru": "Перевод успешно обновлен.", + "ja": "翻訳が正常に更新されました", + "de": "Übersetzung erfolgreich aktualisiert" }, "localeTranslated": { "source": "1 locale translated successfully", "comment": "Snackbar message when exactly 1 locale was auto-translated", "tags": ["browser"], "es": "1 configuración regional traducida correctamente", - "fr-ca": "1 langue traduite avec succès" + "fr-ca": "1 langue traduite avec succès", + "ru": "1 локализация успешно переведена", + "ja": "1つのロケールが正常に翻訳されました", + "de": "1 Gebietsschema erfolgreich übersetzt" }, "localesTranslatedX": { "source": "{count} locales translated successfully", "comment": "Snackbar message when multiple locales were auto-translated", "tags": ["browser"], "es": "{count} locales traducidos correctamente", - "fr-ca": "{count} Les paramètres régionaux ont été traduits avec succès" + "fr-ca": "{count} Les paramètres régionaux ont été traduits avec succès", + "ru": "{count} Локали успешно переведены", + "ja": "{count}ロケールが正常に翻訳されました", + "de": "{count} Gebietsschemas erfolgreich übersetzt" }, "allLocalesUpToDate": { "source": "All locales are already up to date", "comment": "Snackbar message when auto-translate finds nothing to update", "tags": ["browser"], "es": "Todas las configuraciones regionales ya están actualizadas", - "fr-ca": "Tous les emplacements sont déjà à jour." + "fr-ca": "Tous les emplacements sont déjà à jour.", + "ru": "Все языковые версии уже обновлены.", + "ja": "すべての地域は既に最新の状態です", + "de": "Alle Standorte sind bereits auf dem neuesten Stand." }, "skippedLocalesX": { "source": "Skipped locales (ICU format): {locales}", "comment": "Snackbar warning when some locales were skipped because they use ICU format", "tags": ["browser"], "es": "Configuraciones regionales omitidas (formato ICU): {locales}", - "fr-ca": "Paramètres régionaux ignorés (format ICU) : {locales}" + "fr-ca": "Paramètres régionaux ignorés (format ICU) : {locales}", + "ru": "Пропущенные локали (формат ICU): {locales}", + "ja": "スキップされたロケール (ICU 形式): {locales}", + "de": "Übersprungene Gebietsschemas (ICU-Format): {locales}" }, "resourceCreated": { "source": "Resource created successfully", "comment": "Snackbar message after successfully creating a new resource", "tags": ["browser"], "es": "Recurso creado exitosamente", - "fr-ca": "Ressource créée avec succès" + "fr-ca": "Ressource créée avec succès", + "ru": "Ресурс успешно создан.", + "ja": "リソースが正常に作成されました", + "de": "Ressource erfolgreich erstellt" }, "autoTranslationSkippedX": { "source": "Auto-translation skipped for {locales} (ICU format not supported)", "comment": "Snackbar warning when auto-translation was skipped for some locales due to ICU format", "tags": ["browser"], "es": "Se omitió la traducción automática para {locales} (formato ICU no compatible)", - "fr-ca": "Traduction automatique ignorée pour {locales} (format ICU non pris en charge)" + "fr-ca": "Traduction automatique ignorée pour {locales} (format ICU non pris en charge)", + "ru": "Автоматический перевод пропущен для {locales} (формат ICU не поддерживается)", + "ja": "{locales} の自動翻訳はスキップされました(ICU形式はサポートされていません)。", + "de": "Automatische Übersetzung für {locales} übersprungen (ICU-Format wird nicht unterstützt)" }, "resourceAlreadyInFolder": { "source": "Resource is already in this folder", "comment": "Snackbar message when user drops a resource onto its current folder", "tags": ["browser"], "es": "El recurso ya está en esta carpeta", - "fr-ca": "La ressource se trouve déjà dans ce dossier." + "fr-ca": "La ressource se trouve déjà dans ce dossier.", + "ru": "Ресурс уже находится в этой папке.", + "ja": "リソースは既にこのフォルダにあります", + "de": "Die Ressource befindet sich bereits in diesem Ordner" }, "resourceMovedX": { "source": "Moved \"{name}\" to {folder}", "comment": "Snackbar message after moving a resource to a different folder", "tags": ["browser"], "es": "Se movió \"{name}\" a {folder}", - "fr-ca": "Déplacé « {name} » vers {folder}" + "fr-ca": "Déplacé « {name} » vers {folder}", + "ru": "Перемещено \"{name}\" в {folder}", + "ja": "\"{name}\" を {folder} に移動しました。", + "de": "\"{name}\" wurde nach {folder} verschoben." }, "folderAlreadyAtLocation": { "source": "Folder is already at this location", "comment": "Snackbar message when user drops a folder onto its current parent location", "tags": ["browser"], "es": "La carpeta ya está en esta ubicación", - "fr-ca": "Le dossier est déjà à cet emplacement." + "fr-ca": "Le dossier est déjà à cet emplacement.", + "ru": "Папка уже находится по этому адресу.", + "ja": "フォルダは既にこの場所にあります", + "de": "Der Ordner befindet sich bereits an diesem Speicherort" }, "folderMovedX": { "source": "Moved \"{name}\" into {dest}", "comment": "Snackbar message after successfully moving a folder", "tags": ["browser"], "es": "Se movió \"{name}\" a {dest}", - "fr-ca": "Déplacé « {name} » dans {dest}" + "fr-ca": "Déplacé « {name} » dans {dest}", + "ru": "Перемещено \"{name}\" в {dest}", + "ja": "\"{name}\" を {dest} に移動しました。", + "de": "\"{name}\" wurde nach {dest} verschoben." }, "moveResourceFailed": { "source": "Failed to move resource", "comment": "Snackbar error message when moving a resource fails", "tags": ["browser"], "es": "No se pudo mover el recurso", - "fr-ca": "Échec du déplacement de la ressource" + "fr-ca": "Échec du déplacement de la ressource", + "ru": "Не удалось переместить ресурс.", + "ja": "リソースの移動に失敗しました", + "de": "Ressource konnte nicht verschoben werden" }, "moveFolderFailed": { "source": "Failed to move folder", "comment": "Snackbar error message when moving a folder fails", "tags": ["browser"], "es": "No se pudo mover la carpeta", - "fr-ca": "Impossible de déplacer le dossier" + "fr-ca": "Impossible de déplacer le dossier", + "ru": "Не удалось переместить папку.", + "ja": "フォルダの移動に失敗しました", + "de": "Ordner konnte nicht verschoben werden" }, "loadFoldersFailed": { "source": "Failed to load folders", "comment": "Snackbar/error message when loading the folder tree fails", "tags": ["browser"], "es": "No se pudieron cargar las carpetas", - "fr-ca": "Échec du chargement des dossiers" + "fr-ca": "Échec du chargement des dossiers", + "ru": "Не удалось загрузить папки.", + "ja": "フォルダの読み込みに失敗しました", + "de": "Ordner konnten nicht geladen werden" }, "loadFolderChildrenFailed": { "source": "Failed to load folder contents", "comment": "Snackbar/error message when loading a folder's children fails", "tags": ["browser"], "es": "No se pudo cargar el contenido de la carpeta", - "fr-ca": "Impossible de charger le contenu du dossier" + "fr-ca": "Impossible de charger le contenu du dossier", + "ru": "Не удалось загрузить содержимое папки.", + "ja": "フォルダの内容の読み込みに失敗しました", + "de": "Ordnerinhalt konnte nicht geladen werden" }, "createFolderFailed": { "source": "Failed to create folder", "comment": "Snackbar/error message when creating a folder fails", "tags": ["browser"], "es": "Error al crear la carpeta", - "fr-ca": "Impossible de créer le dossier" + "fr-ca": "Impossible de créer le dossier", + "ru": "Не удалось создать папку.", + "ja": "フォルダの作成に失敗しました", + "de": "Ordner konnte nicht erstellt werden" }, "deleteFolderFailed": { "source": "Failed to delete folder", "comment": "Snackbar/error message when deleting a folder fails", "tags": ["browser"], "es": "No se pudo eliminar la carpeta", - "fr-ca": "Échec de la suppression du dossier" + "fr-ca": "Échec de la suppression du dossier", + "ru": "Не удалось удалить папку.", + "ja": "フォルダの削除に失敗しました", + "de": "Ordner konnte nicht gelöscht werden" }, "loadTranslationsFailed": { "source": "Failed to load translations", "comment": "Snackbar/error message when loading translations for a folder fails", "tags": ["browser"], "es": "No se pudieron cargar las traducciones", - "fr-ca": "Impossible de charger les traductions" + "fr-ca": "Impossible de charger les traductions", + "ru": "Не удалось загрузить переводы.", + "ja": "翻訳の読み込みに失敗しました", + "de": "Übersetzungen konnten nicht geladen werden" }, "searchTranslationsFailed": { "source": "Failed to search translations", "comment": "Snackbar/error message when searching translations fails", "tags": ["browser"], "es": "No se pudo buscar traducciones", - "fr-ca": "Échec de la recherche de traductions" + "fr-ca": "Échec de la recherche de traductions", + "ru": "Поиск переводов не удался.", + "ja": "翻訳の検索に失敗しました", + "de": "Übersetzungssuche fehlgeschlagen" }, "checkCacheStatusFailed": { "source": "Failed to check cache status", "comment": "Snackbar/error message when checking cache status fails", "tags": ["browser"], "es": "No se pudo comprobar el estado de la caché", - "fr-ca": "Échec de la vérification de l'état du cache" + "fr-ca": "Échec de la vérification de l'état du cache", + "ru": "Не удалось проверить состояние кэша.", + "ja": "キャッシュの状態を確認できませんでした", + "de": "Cache-Statusprüfung fehlgeschlagen" } } diff --git a/apps/tracker/src/i18n/browser/toast/tracker_meta.json b/apps/tracker/src/i18n/browser/toast/tracker_meta.json index 46ec82b8..c0eaacd2 100644 --- a/apps/tracker/src/i18n/browser/toast/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/toast/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "268147c8e3596b09d44cb181b561428a", "baseChecksum": "efc1a46f7b47e4d3cf60f13b6c89069b", "status": "translated" + }, + "ru": { + "checksum": "ec92bc41e416d8493fcdeb3629e87e12", + "baseChecksum": "efc1a46f7b47e4d3cf60f13b6c89069b", + "status": "translated" + }, + "ja": { + "checksum": "567229e0a6700867940999093ce6c150", + "baseChecksum": "efc1a46f7b47e4d3cf60f13b6c89069b", + "status": "translated" + }, + "de": { + "checksum": "b32999852b549dbfc75820c8d5fcd08f", + "baseChecksum": "efc1a46f7b47e4d3cf60f13b6c89069b", + "status": "translated" } }, "copyFailed": { @@ -27,6 +42,21 @@ "checksum": "7ceeff034e95092dd8798b12ba572014", "baseChecksum": "e608b2fe7089e4fa80b73b4f9c03fb61", "status": "translated" + }, + "ru": { + "checksum": "c63eb8553a973244e9929fb545ba6a68", + "baseChecksum": "e608b2fe7089e4fa80b73b4f9c03fb61", + "status": "translated" + }, + "ja": { + "checksum": "a3be8780485e9d6cb6ac1b61fe24e2cb", + "baseChecksum": "e608b2fe7089e4fa80b73b4f9c03fb61", + "status": "translated" + }, + "de": { + "checksum": "eee387fa8f8f8ee4d3446cfe9fcfe545", + "baseChecksum": "e608b2fe7089e4fa80b73b4f9c03fb61", + "status": "translated" } }, "resourceDeleted": { @@ -42,6 +72,21 @@ "checksum": "92d90883ff585b842a35c8363f678655", "baseChecksum": "b9dceafaee589a43841583ca0adf0f8a", "status": "translated" + }, + "ru": { + "checksum": "cdef260bd827cc2954ca546bd851a2ed", + "baseChecksum": "b9dceafaee589a43841583ca0adf0f8a", + "status": "translated" + }, + "ja": { + "checksum": "ed7e19297885ad43185af933ad4b591a", + "baseChecksum": "b9dceafaee589a43841583ca0adf0f8a", + "status": "translated" + }, + "de": { + "checksum": "01add228d99d5268a74a240634554bf0", + "baseChecksum": "b9dceafaee589a43841583ca0adf0f8a", + "status": "translated" } }, "deleteFailed": { @@ -57,6 +102,21 @@ "checksum": "05975cae9b6c3501daec707df958e785", "baseChecksum": "ca16c7c92425038d9b8b85c10763a3f4", "status": "translated" + }, + "ru": { + "checksum": "75514f822bae3ee2a45d8fe6d3e8e421", + "baseChecksum": "ca16c7c92425038d9b8b85c10763a3f4", + "status": "translated" + }, + "ja": { + "checksum": "65c480803307a8e07e3d746049e9a2c9", + "baseChecksum": "ca16c7c92425038d9b8b85c10763a3f4", + "status": "translated" + }, + "de": { + "checksum": "33f6079675ae8a0fc74b6e5ac4422fc0", + "baseChecksum": "ca16c7c92425038d9b8b85c10763a3f4", + "status": "translated" } }, "translateFailed": { @@ -72,6 +132,21 @@ "checksum": "a2adc3c747b0f69549289f153cecfee1", "baseChecksum": "45df2fc42204ed770ef53245a8361e7c", "status": "translated" + }, + "ru": { + "checksum": "06b361d1480d6c99691ae65506106ce0", + "baseChecksum": "45df2fc42204ed770ef53245a8361e7c", + "status": "translated" + }, + "ja": { + "checksum": "83f4cb2702bdddf2fb205fa75e256699", + "baseChecksum": "45df2fc42204ed770ef53245a8361e7c", + "status": "translated" + }, + "de": { + "checksum": "bdc34d732fffcb7d131ecfa96383e84d", + "baseChecksum": "45df2fc42204ed770ef53245a8361e7c", + "status": "translated" } }, "translationUpdated": { @@ -87,6 +162,21 @@ "checksum": "2cc24444af0b79d681653805cd376e9c", "baseChecksum": "9b49c277e489463f1ef5a98e51b6bf7a", "status": "translated" + }, + "ru": { + "checksum": "8758846c4d762ef7ae23f64c9e8a37ee", + "baseChecksum": "9b49c277e489463f1ef5a98e51b6bf7a", + "status": "translated" + }, + "ja": { + "checksum": "fee19bc8be44363a06fa197fa44bc1c1", + "baseChecksum": "9b49c277e489463f1ef5a98e51b6bf7a", + "status": "translated" + }, + "de": { + "checksum": "8c31e1d50dde54c5c41f0979ab13a923", + "baseChecksum": "9b49c277e489463f1ef5a98e51b6bf7a", + "status": "translated" } }, "localeTranslated": { @@ -102,6 +192,21 @@ "checksum": "10c74d6d7bb35c14ba0780659f54fddb", "baseChecksum": "f46fd3b7fe7b9890ffa12a9a942374d5", "status": "translated" + }, + "ru": { + "checksum": "67fd8872d020382bd67558d32e6820df", + "baseChecksum": "f46fd3b7fe7b9890ffa12a9a942374d5", + "status": "translated" + }, + "ja": { + "checksum": "d8d473fa85d270c7dc402ed06e3512ab", + "baseChecksum": "f46fd3b7fe7b9890ffa12a9a942374d5", + "status": "translated" + }, + "de": { + "checksum": "f10f6d0c2553c0b49ffcf9947b89c86f", + "baseChecksum": "f46fd3b7fe7b9890ffa12a9a942374d5", + "status": "translated" } }, "localesTranslatedX": { @@ -117,6 +222,21 @@ "checksum": "4f6287f9046e691e34937001de08903a", "baseChecksum": "5b843fe3323928bdd2c3412679c86ff7", "status": "stale" + }, + "ru": { + "checksum": "f9eb75bd7974a61268f85076bdc71336", + "baseChecksum": "5b843fe3323928bdd2c3412679c86ff7", + "status": "translated" + }, + "ja": { + "checksum": "a89ae0122ac838d74151d8fdc99b0f41", + "baseChecksum": "5b843fe3323928bdd2c3412679c86ff7", + "status": "translated" + }, + "de": { + "checksum": "2634193f03a7466b10997efff1144378", + "baseChecksum": "5b843fe3323928bdd2c3412679c86ff7", + "status": "translated" } }, "allLocalesUpToDate": { @@ -132,6 +252,21 @@ "checksum": "03f4b571a5a6cf7479d0309b7c715c64", "baseChecksum": "d2e14c662112dbc29340558b10c0c2f1", "status": "translated" + }, + "ru": { + "checksum": "025845ef981f5263abff0bc625c0bb26", + "baseChecksum": "d2e14c662112dbc29340558b10c0c2f1", + "status": "translated" + }, + "ja": { + "checksum": "4babafabb40626c8ba9b8c1ac9e46e42", + "baseChecksum": "d2e14c662112dbc29340558b10c0c2f1", + "status": "translated" + }, + "de": { + "checksum": "c3fe3e809216d73b0ea37b27fefb2718", + "baseChecksum": "d2e14c662112dbc29340558b10c0c2f1", + "status": "translated" } }, "skippedLocalesX": { @@ -147,6 +282,21 @@ "checksum": "3e2002568171f1bdc4522b46ec7ec405", "baseChecksum": "12a69e024b35f9a21939d29f767e0821", "status": "stale" + }, + "ru": { + "checksum": "ef143d7f4fd08c61ba32621f5857a02f", + "baseChecksum": "12a69e024b35f9a21939d29f767e0821", + "status": "translated" + }, + "ja": { + "checksum": "38a1151aec569dbf7cca1278a65ca866", + "baseChecksum": "12a69e024b35f9a21939d29f767e0821", + "status": "translated" + }, + "de": { + "checksum": "6f4f5ba950d24835cd8ea53bdc4b128b", + "baseChecksum": "12a69e024b35f9a21939d29f767e0821", + "status": "translated" } }, "resourceCreated": { @@ -162,6 +312,21 @@ "checksum": "d52e76c679ab1c16c0cc9af2deb506f3", "baseChecksum": "b2d6f92f9f0cb77d851b3aa960acb05d", "status": "translated" + }, + "ru": { + "checksum": "fe46f75147afda125972f7952101f910", + "baseChecksum": "b2d6f92f9f0cb77d851b3aa960acb05d", + "status": "translated" + }, + "ja": { + "checksum": "621251f5001e39bcce4c88ab48dafaa6", + "baseChecksum": "b2d6f92f9f0cb77d851b3aa960acb05d", + "status": "translated" + }, + "de": { + "checksum": "33122f102a53bb0f1c6723ab8a017f69", + "baseChecksum": "b2d6f92f9f0cb77d851b3aa960acb05d", + "status": "translated" } }, "autoTranslationSkippedX": { @@ -177,6 +342,21 @@ "checksum": "cefd9cff1fd03bfbdd9c599dc415fcde", "baseChecksum": "760c64588bcdc219130e6209f46db428", "status": "stale" + }, + "ru": { + "checksum": "e7141f32408f357995b006d9ad1fc8db", + "baseChecksum": "760c64588bcdc219130e6209f46db428", + "status": "translated" + }, + "ja": { + "checksum": "b702c32653d30d3b174ade0acc4c0d1c", + "baseChecksum": "760c64588bcdc219130e6209f46db428", + "status": "translated" + }, + "de": { + "checksum": "a26cad4d493f9b67e212566ad08ea7c8", + "baseChecksum": "760c64588bcdc219130e6209f46db428", + "status": "translated" } }, "resourceAlreadyInFolder": { @@ -192,6 +372,21 @@ "checksum": "abcc113acafc2cc0585ca1265e97f775", "baseChecksum": "1c1333bc0019d4cf30f4a561ab5b371e", "status": "translated" + }, + "ru": { + "checksum": "649e37b9c72cdc2b1391f6a007f09bde", + "baseChecksum": "1c1333bc0019d4cf30f4a561ab5b371e", + "status": "translated" + }, + "ja": { + "checksum": "03360edfbb1d351e04a12caaa6b4f0a7", + "baseChecksum": "1c1333bc0019d4cf30f4a561ab5b371e", + "status": "translated" + }, + "de": { + "checksum": "d30c1594f697d5060c0fad9d268447a2", + "baseChecksum": "1c1333bc0019d4cf30f4a561ab5b371e", + "status": "translated" } }, "resourceMovedX": { @@ -207,6 +402,21 @@ "checksum": "c1adc37f0a52cd2c618c0f58cb80ae7e", "baseChecksum": "ce40eefa32c87be1fc1a51d276eeb2a0", "status": "stale" + }, + "ru": { + "checksum": "57ed621db988e0ff2452dd3ceba888de", + "baseChecksum": "ce40eefa32c87be1fc1a51d276eeb2a0", + "status": "translated" + }, + "ja": { + "checksum": "b9747d860acd91f2caeacf54b50aa10f", + "baseChecksum": "ce40eefa32c87be1fc1a51d276eeb2a0", + "status": "translated" + }, + "de": { + "checksum": "3a9da16c7daeb348353271c47698c981", + "baseChecksum": "ce40eefa32c87be1fc1a51d276eeb2a0", + "status": "translated" } }, "folderAlreadyAtLocation": { @@ -222,6 +432,21 @@ "checksum": "75bd782c6687cca95a821b7ecb035c26", "baseChecksum": "b619e21511fa7943627eaaa33b976d8a", "status": "translated" + }, + "ru": { + "checksum": "6cdea52f8679f1066433331ba737c10b", + "baseChecksum": "b619e21511fa7943627eaaa33b976d8a", + "status": "translated" + }, + "ja": { + "checksum": "1c280dce184bc9507906e14f5d58e70a", + "baseChecksum": "b619e21511fa7943627eaaa33b976d8a", + "status": "translated" + }, + "de": { + "checksum": "0bc771bfa6e7b1124f6cf73e70595e60", + "baseChecksum": "b619e21511fa7943627eaaa33b976d8a", + "status": "translated" } }, "folderMovedX": { @@ -237,6 +462,21 @@ "checksum": "0401d563667e407bac3518529dc6de20", "baseChecksum": "e1ad81924f3ed1eec2bc567968949971", "status": "stale" + }, + "ru": { + "checksum": "0a01d88a69798347a9f7c46d2737fb00", + "baseChecksum": "e1ad81924f3ed1eec2bc567968949971", + "status": "translated" + }, + "ja": { + "checksum": "85b8f85868a900049b2b053d2f358252", + "baseChecksum": "e1ad81924f3ed1eec2bc567968949971", + "status": "translated" + }, + "de": { + "checksum": "ae0f094e1d7fd5480dd72bbc8757cd2d", + "baseChecksum": "e1ad81924f3ed1eec2bc567968949971", + "status": "translated" } }, "moveResourceFailed": { @@ -252,6 +492,21 @@ "checksum": "8323fd4409ccd85e74540da933d6a7ae", "baseChecksum": "d7e32b8caa55d48161461d5cc8b7ac96", "status": "translated" + }, + "ru": { + "checksum": "aee0145a06c50bf66cd84d7cf9a89166", + "baseChecksum": "d7e32b8caa55d48161461d5cc8b7ac96", + "status": "translated" + }, + "ja": { + "checksum": "0ca4fd45835da010826489a941689033", + "baseChecksum": "d7e32b8caa55d48161461d5cc8b7ac96", + "status": "translated" + }, + "de": { + "checksum": "dfbf578be8c99a40893fd3a8ea698a41", + "baseChecksum": "d7e32b8caa55d48161461d5cc8b7ac96", + "status": "translated" } }, "moveFolderFailed": { @@ -267,6 +522,21 @@ "checksum": "6217e64964af6ca91846202a3f8f8ca1", "baseChecksum": "65f31a3448a52e23c12b3140f0bb722f", "status": "translated" + }, + "ru": { + "checksum": "0327a27e4d4b75e0667b8c931f45248d", + "baseChecksum": "65f31a3448a52e23c12b3140f0bb722f", + "status": "translated" + }, + "ja": { + "checksum": "196bfc492480dc88d3629161a5b12a07", + "baseChecksum": "65f31a3448a52e23c12b3140f0bb722f", + "status": "translated" + }, + "de": { + "checksum": "3d66fd04dc0a47daa2061f3c7beda2aa", + "baseChecksum": "65f31a3448a52e23c12b3140f0bb722f", + "status": "translated" } }, "loadFoldersFailed": { @@ -282,6 +552,21 @@ "checksum": "a4bcca17dbf208208f3165169c0f958a", "baseChecksum": "5066e552105a8542039601e3df9b26c8", "status": "translated" + }, + "ru": { + "checksum": "2bb1d38671ee0d072212e76a04238167", + "baseChecksum": "5066e552105a8542039601e3df9b26c8", + "status": "translated" + }, + "ja": { + "checksum": "851684cb4047dee5dc52c288ce2e6c5f", + "baseChecksum": "5066e552105a8542039601e3df9b26c8", + "status": "translated" + }, + "de": { + "checksum": "0382001703b16a0740b074132654bc3c", + "baseChecksum": "5066e552105a8542039601e3df9b26c8", + "status": "translated" } }, "loadFolderChildrenFailed": { @@ -297,6 +582,21 @@ "checksum": "78b55839e8544cf842b43d3023f63e54", "baseChecksum": "5781e96b921ead1d96ae579c13a1db41", "status": "translated" + }, + "ru": { + "checksum": "e269d5b86aed9cb090df1bf0802d9384", + "baseChecksum": "5781e96b921ead1d96ae579c13a1db41", + "status": "translated" + }, + "ja": { + "checksum": "9306c7d6e961819940e1c6583167cfe8", + "baseChecksum": "5781e96b921ead1d96ae579c13a1db41", + "status": "translated" + }, + "de": { + "checksum": "55f27cead152bb92a029c7a1924c77e3", + "baseChecksum": "5781e96b921ead1d96ae579c13a1db41", + "status": "translated" } }, "createFolderFailed": { @@ -312,6 +612,21 @@ "checksum": "3a8006f316f0b8e692ca464c5c728c70", "baseChecksum": "398dff483997d01292f5848d5f78e409", "status": "translated" + }, + "ru": { + "checksum": "5c86bb3f4b6b381f42094b79f6e2ba62", + "baseChecksum": "398dff483997d01292f5848d5f78e409", + "status": "translated" + }, + "ja": { + "checksum": "653707d6996bec51f6bbd51b29d7aee7", + "baseChecksum": "398dff483997d01292f5848d5f78e409", + "status": "translated" + }, + "de": { + "checksum": "7cbd86dab907a1f49ee0fcf5ea2ac8e2", + "baseChecksum": "398dff483997d01292f5848d5f78e409", + "status": "translated" } }, "deleteFolderFailed": { @@ -327,6 +642,21 @@ "checksum": "a9663707070e677cbf3f693a6dc9864d", "baseChecksum": "f0a2fda292f25e75c594d8497d81151d", "status": "translated" + }, + "ru": { + "checksum": "7c833db5ea6801e338392f8251288b6c", + "baseChecksum": "f0a2fda292f25e75c594d8497d81151d", + "status": "translated" + }, + "ja": { + "checksum": "7b0bd7e619dd498dac3d246131c18b6a", + "baseChecksum": "f0a2fda292f25e75c594d8497d81151d", + "status": "translated" + }, + "de": { + "checksum": "ebbb3bde16388d8d91b91db2e1ec8cc4", + "baseChecksum": "f0a2fda292f25e75c594d8497d81151d", + "status": "translated" } }, "loadTranslationsFailed": { @@ -342,6 +672,21 @@ "checksum": "cb2f25e022138485885b48ec4c92214c", "baseChecksum": "aa4bb30ab9d42c5b447f978775d08b81", "status": "translated" + }, + "ru": { + "checksum": "5d7464d26544e7d3f675d1760886bfcb", + "baseChecksum": "aa4bb30ab9d42c5b447f978775d08b81", + "status": "translated" + }, + "ja": { + "checksum": "5a7c357a2dce728b5b7b92beee873151", + "baseChecksum": "aa4bb30ab9d42c5b447f978775d08b81", + "status": "translated" + }, + "de": { + "checksum": "ca42f67bc440f2afd34ea934c04567cd", + "baseChecksum": "aa4bb30ab9d42c5b447f978775d08b81", + "status": "translated" } }, "searchTranslationsFailed": { @@ -357,6 +702,21 @@ "checksum": "e56b3fca1a74fb8ec065a62f26ae0120", "baseChecksum": "fb7a3ff2067a6021abacc204764deb27", "status": "translated" + }, + "ru": { + "checksum": "80ba7aef9d007e5515bbf8b82a5e5e58", + "baseChecksum": "fb7a3ff2067a6021abacc204764deb27", + "status": "translated" + }, + "ja": { + "checksum": "0dda7860a9bbfab0b96d9291d72cf9c4", + "baseChecksum": "fb7a3ff2067a6021abacc204764deb27", + "status": "translated" + }, + "de": { + "checksum": "2c84d8dc394a3d8545d97f1cf08ec1ce", + "baseChecksum": "fb7a3ff2067a6021abacc204764deb27", + "status": "translated" } }, "checkCacheStatusFailed": { @@ -372,6 +732,21 @@ "checksum": "f32ed5ed5b787f4bb8d41daf1bebdb14", "baseChecksum": "c36227ebfa47873e719514df95f28888", "status": "translated" + }, + "ru": { + "checksum": "cac79a23a3050bf41a3458c7829a65f1", + "baseChecksum": "c36227ebfa47873e719514df95f28888", + "status": "translated" + }, + "ja": { + "checksum": "0c38c42a7b104d56898638166bf15cb1", + "baseChecksum": "c36227ebfa47873e719514df95f28888", + "status": "translated" + }, + "de": { + "checksum": "043e0595853efd4798f7578c1d256a91", + "baseChecksum": "c36227ebfa47873e719514df95f28888", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/tracker_meta.json b/apps/tracker/src/i18n/browser/tracker_meta.json index 2dd36671..a0f4437b 100644 --- a/apps/tracker/src/i18n/browser/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "73586b8c21ceaebfb82eeaaf5378439c", "baseChecksum": "b09a15708fbea9ef383087bf01b4f47f", "status": "translated" + }, + "ru": { + "checksum": "fa210ccd7b7d9347d63fbc720faeb1bf", + "baseChecksum": "b09a15708fbea9ef383087bf01b4f47f", + "status": "translated" + }, + "ja": { + "checksum": "826da54bd00eb095a391f518f9241381", + "baseChecksum": "b09a15708fbea9ef383087bf01b4f47f", + "status": "translated" + }, + "de": { + "checksum": "f4663967ea5bc4f80db9cdadde1d909e", + "baseChecksum": "b09a15708fbea9ef383087bf01b4f47f", + "status": "translated" } }, "filterFolders": { @@ -27,6 +42,21 @@ "checksum": "061ee375bfde90bfce0720a21d2313b9", "baseChecksum": "4e0bb967b51a78b8b8ba8c6417045ca3", "status": "translated" + }, + "ru": { + "checksum": "9078189387de2fe62f86b0d851c68b7b", + "baseChecksum": "4e0bb967b51a78b8b8ba8c6417045ca3", + "status": "translated" + }, + "ja": { + "checksum": "5fcf227d8db466f32f42733156da35e1", + "baseChecksum": "4e0bb967b51a78b8b8ba8c6417045ca3", + "status": "translated" + }, + "de": { + "checksum": "f6ec990c320763ced1735ca79fbc62fc", + "baseChecksum": "4e0bb967b51a78b8b8ba8c6417045ca3", + "status": "translated" } }, "loadingFolders": { @@ -42,6 +72,21 @@ "checksum": "649d4e3e7edf9dceba52abc26c37b7f7", "baseChecksum": "eed63f5e6c0eed3660954f4db33c341d", "status": "translated" + }, + "ru": { + "checksum": "df5432f9517649a4f409d30cc2e9d8a5", + "baseChecksum": "eed63f5e6c0eed3660954f4db33c341d", + "status": "translated" + }, + "ja": { + "checksum": "b5dabea2eb0cea29b27b97dbf2407923", + "baseChecksum": "eed63f5e6c0eed3660954f4db33c341d", + "status": "translated" + }, + "de": { + "checksum": "0a8d3fa12f6f295b4971335e1a363d35", + "baseChecksum": "eed63f5e6c0eed3660954f4db33c341d", + "status": "translated" } }, "noFoldersMatchSearch": { @@ -57,6 +102,21 @@ "checksum": "11c5d6f0f3bdb3ec235782d7cfa73cf9", "baseChecksum": "98103e256bcf8b8d056c6c57e182af94", "status": "translated" + }, + "ru": { + "checksum": "2859dc31bb46a00eb851216edaeb81e2", + "baseChecksum": "98103e256bcf8b8d056c6c57e182af94", + "status": "translated" + }, + "ja": { + "checksum": "216553c9108f0e0516a4de96430bd572", + "baseChecksum": "98103e256bcf8b8d056c6c57e182af94", + "status": "translated" + }, + "de": { + "checksum": "76b28c2950fd0afb69d342ab9edfe939", + "baseChecksum": "98103e256bcf8b8d056c6c57e182af94", + "status": "translated" } }, "noFoldersFound": { @@ -72,6 +132,21 @@ "checksum": "38ea1e5ce43d5c68b87ce14ca60d6b3d", "baseChecksum": "1d4fc1a925ee14980d2465e73cfcbd8b", "status": "translated" + }, + "ru": { + "checksum": "5e9f67a2b830d84f57632a0835ddaa1b", + "baseChecksum": "1d4fc1a925ee14980d2465e73cfcbd8b", + "status": "translated" + }, + "ja": { + "checksum": "d20464ad8dd7a7fa6ab1ad8eaebab662", + "baseChecksum": "1d4fc1a925ee14980d2465e73cfcbd8b", + "status": "translated" + }, + "de": { + "checksum": "9ebe46a9e014a1bb67148ca721ab5f44", + "baseChecksum": "1d4fc1a925ee14980d2465e73cfcbd8b", + "status": "translated" } }, "clickToLoad": { @@ -87,6 +162,21 @@ "checksum": "7141789d79a55dd857a5d689f99134fd", "baseChecksum": "73c67a917acc1f58d962462b80209a2d", "status": "translated" + }, + "ru": { + "checksum": "3d9a1da51f9facd70f9fca121afc47f8", + "baseChecksum": "73c67a917acc1f58d962462b80209a2d", + "status": "translated" + }, + "ja": { + "checksum": "753b3a43383a36cbbfe5dca93544d005", + "baseChecksum": "73c67a917acc1f58d962462b80209a2d", + "status": "translated" + }, + "de": { + "checksum": "4e9e29c46ac207845b4b9cdb89439bfc", + "baseChecksum": "73c67a917acc1f58d962462b80209a2d", + "status": "translated" } }, "loadingCollectionConfiguration": { @@ -102,6 +192,21 @@ "checksum": "8caaf7bef2d55d92cdfb8f13d25ea92d", "baseChecksum": "8f859dd0cadf2db6737aa2340aceac45", "status": "translated" + }, + "ru": { + "checksum": "0ef07a4f718fb85f3a3faae1347bfff8", + "baseChecksum": "8f859dd0cadf2db6737aa2340aceac45", + "status": "translated" + }, + "ja": { + "checksum": "b5045b5c8ccce22507cdd309cea075dc", + "baseChecksum": "8f859dd0cadf2db6737aa2340aceac45", + "status": "translated" + }, + "de": { + "checksum": "dc18f6721c03afc88f400fc78a934b2d", + "baseChecksum": "8f859dd0cadf2db6737aa2340aceac45", + "status": "translated" } }, "loadingTranslations": { @@ -117,6 +222,21 @@ "checksum": "f622bdfabe2c272bd0a46f7fa6132266", "baseChecksum": "a20f347327bc7ebdad2e167fdd8fd389", "status": "translated" + }, + "ru": { + "checksum": "bd9770c77e861ad2ab36e46e4044fbde", + "baseChecksum": "a20f347327bc7ebdad2e167fdd8fd389", + "status": "translated" + }, + "ja": { + "checksum": "abc27a8d5e2687c524c2d8952d5dc814", + "baseChecksum": "a20f347327bc7ebdad2e167fdd8fd389", + "status": "translated" + }, + "de": { + "checksum": "7aa2529f4eb106b2cdf2e21894a666ce", + "baseChecksum": "a20f347327bc7ebdad2e167fdd8fd389", + "status": "translated" } }, "noTranslationsFoundInFolder": { @@ -132,6 +252,21 @@ "checksum": "a00261766c6d528c1579a34454baa740", "baseChecksum": "b0537eb5b23d6c452ec6844ab366473c", "status": "translated" + }, + "ru": { + "checksum": "2527f79457eacc89234bc006d8d7489c", + "baseChecksum": "b0537eb5b23d6c452ec6844ab366473c", + "status": "translated" + }, + "ja": { + "checksum": "5804cbd021df71d58e6abdb672a54214", + "baseChecksum": "b0537eb5b23d6c452ec6844ab366473c", + "status": "translated" + }, + "de": { + "checksum": "d3497a4ed0488ac3d8e5adabed054cc1", + "baseChecksum": "b0537eb5b23d6c452ec6844ab366473c", + "status": "translated" } }, "searchTranslations": { @@ -147,6 +282,21 @@ "checksum": "e2f36f41dc8108041a066fdddff7a139", "baseChecksum": "665bc5147e529958fe65fecdbed4ebe4", "status": "stale" + }, + "ru": { + "checksum": "c5510b402837c0bbc123de68a1d0f7a3", + "baseChecksum": "665bc5147e529958fe65fecdbed4ebe4", + "status": "translated" + }, + "ja": { + "checksum": "a08e08bcd107b1987fc75bcfcc06d088", + "baseChecksum": "665bc5147e529958fe65fecdbed4ebe4", + "status": "translated" + }, + "de": { + "checksum": "857cf95089cd7bd5df4cad85b0c01dc9", + "baseChecksum": "665bc5147e529958fe65fecdbed4ebe4", + "status": "translated" } }, "showingSearchResultsForX": { @@ -162,6 +312,21 @@ "checksum": "a22904d2b9649f73fbe9345e9fd6cbb7", "baseChecksum": "80bc1784503c24bf76c6291216ff6bf2", "status": "stale" + }, + "ru": { + "checksum": "db3a954f90518769a688706acec4b614", + "baseChecksum": "80bc1784503c24bf76c6291216ff6bf2", + "status": "translated" + }, + "ja": { + "checksum": "2d11da26c6236435857b7c04a6974b78", + "baseChecksum": "80bc1784503c24bf76c6291216ff6bf2", + "status": "translated" + }, + "de": { + "checksum": "094f5904680816444ce5479fddcfeca8", + "baseChecksum": "80bc1784503c24bf76c6291216ff6bf2", + "status": "translated" } }, "clearSearch": { @@ -177,6 +342,21 @@ "checksum": "00b965402c9687499607c2b4792a5bdf", "baseChecksum": "9b39ba5cc7e59ddc8fc7b5c371d0db67", "status": "translated" + }, + "ru": { + "checksum": "30e2d4974208e7be2d9a8e7e58f8adf4", + "baseChecksum": "9b39ba5cc7e59ddc8fc7b5c371d0db67", + "status": "translated" + }, + "ja": { + "checksum": "2b4c324620a1bbb4bb69b5c878b817f8", + "baseChecksum": "9b39ba5cc7e59ddc8fc7b5c371d0db67", + "status": "translated" + }, + "de": { + "checksum": "ff36602c0d2eb517aeeff170649f45dd", + "baseChecksum": "9b39ba5cc7e59ddc8fc7b5c371d0db67", + "status": "translated" } }, "noFolderSelected": { @@ -192,6 +372,21 @@ "checksum": "5e226109277717898c62d35e01a0b102", "baseChecksum": "c6dafc9139d28bfba06ab787b68a03e4", "status": "translated" + }, + "ru": { + "checksum": "bd56afdcb901f2da743aa5d1aaae8c18", + "baseChecksum": "c6dafc9139d28bfba06ab787b68a03e4", + "status": "translated" + }, + "ja": { + "checksum": "a451284da105a6a43b836b542ea3fe6d", + "baseChecksum": "c6dafc9139d28bfba06ab787b68a03e4", + "status": "translated" + }, + "de": { + "checksum": "804ac30a828b033c7d81ef57d2da04dc", + "baseChecksum": "c6dafc9139d28bfba06ab787b68a03e4", + "status": "translated" } }, "addTranslationButton": { @@ -207,6 +402,21 @@ "checksum": "49b452807807f78aa4c6921db1eef68f", "baseChecksum": "cb00aa2dec0df9333114919825e4883b", "status": "translated" + }, + "ru": { + "checksum": "b4978cefca449b5f01784658cdc3af50", + "baseChecksum": "cb00aa2dec0df9333114919825e4883b", + "status": "translated" + }, + "ja": { + "checksum": "1ed69309dc713cdd954e5288f6af6cb2", + "baseChecksum": "cb00aa2dec0df9333114919825e4883b", + "status": "translated" + }, + "de": { + "checksum": "1ab31f8633950df62d5baae1528f9b07", + "baseChecksum": "cb00aa2dec0df9333114919825e4883b", + "status": "translated" } }, "sortAscending": { @@ -222,6 +432,21 @@ "checksum": "ba4a2dcd0ab328476a0708224ac1579a", "baseChecksum": "bc01377158f11789893c21fac7a21477", "status": "translated" + }, + "ru": { + "checksum": "df24ffa5304e28ab9c2040d9de5321ef", + "baseChecksum": "bc01377158f11789893c21fac7a21477", + "status": "translated" + }, + "ja": { + "checksum": "0f4cb7f9d1776c7b209e278dcdc769f0", + "baseChecksum": "bc01377158f11789893c21fac7a21477", + "status": "translated" + }, + "de": { + "checksum": "ac2f6a4c3080be3df2281d2cc4166f95", + "baseChecksum": "bc01377158f11789893c21fac7a21477", + "status": "translated" } }, "sortDescending": { @@ -237,6 +462,21 @@ "checksum": "a569b2bb297a2a71dbd8de8954108932", "baseChecksum": "acc4a932d537143388dfc72a8c5ec2b9", "status": "translated" + }, + "ru": { + "checksum": "5cbc68bf05d0bb56bfb3958d010713ae", + "baseChecksum": "acc4a932d537143388dfc72a8c5ec2b9", + "status": "translated" + }, + "ja": { + "checksum": "2166a8d2c8d100de97fdc0864f2784d8", + "baseChecksum": "acc4a932d537143388dfc72a8c5ec2b9", + "status": "translated" + }, + "de": { + "checksum": "168e3a586d90aecb7ded2b9cacb5e261", + "baseChecksum": "acc4a932d537143388dfc72a8c5ec2b9", + "status": "translated" } }, "sortAscendingTooltip": { @@ -252,6 +492,21 @@ "checksum": "2ca0ed42a9fee5256e3eaf78b52169b6", "baseChecksum": "153ebaf4ed71cc3878ef37acd79e6979", "status": "translated" + }, + "ru": { + "checksum": "5d9f4c7ce1400ef1e553973d3179b3c3", + "baseChecksum": "153ebaf4ed71cc3878ef37acd79e6979", + "status": "translated" + }, + "ja": { + "checksum": "1e31674cda89acfc45e3c2783a9e4d60", + "baseChecksum": "153ebaf4ed71cc3878ef37acd79e6979", + "status": "translated" + }, + "de": { + "checksum": "12691a65c81dd0ccadba1865a65c2386", + "baseChecksum": "153ebaf4ed71cc3878ef37acd79e6979", + "status": "translated" } }, "sortDescendingTooltip": { @@ -267,6 +522,21 @@ "checksum": "e9e2a83a580e5b183df4a6e9694dc239", "baseChecksum": "45bacec41cc0c3735415f3e76813f41d", "status": "translated" + }, + "ru": { + "checksum": "4fb2227228b1fd2c3d45482ae824414d", + "baseChecksum": "45bacec41cc0c3735415f3e76813f41d", + "status": "translated" + }, + "ja": { + "checksum": "1dacc5dc70f308a5805a13f5723db6f4", + "baseChecksum": "45bacec41cc0c3735415f3e76813f41d", + "status": "translated" + }, + "de": { + "checksum": "ecd386beee6073fef3212fd11904c6e3", + "baseChecksum": "45bacec41cc0c3735415f3e76813f41d", + "status": "translated" } }, "selectFolderFirst": { @@ -282,6 +552,21 @@ "checksum": "2d975dbf2e3f83915e39ce6f550724cb", "baseChecksum": "addf30815d3754a3170b8d0d9b3f7196", "status": "translated" + }, + "ru": { + "checksum": "55a41223d9c642c59c0ff06f085d27a6", + "baseChecksum": "addf30815d3754a3170b8d0d9b3f7196", + "status": "translated" + }, + "ja": { + "checksum": "9586322b0e1c3ac2016a8878266fde6e", + "baseChecksum": "addf30815d3754a3170b8d0d9b3f7196", + "status": "translated" + }, + "de": { + "checksum": "25dd264201a52111b9b20ad7d6e9b37d", + "baseChecksum": "addf30815d3754a3170b8d0d9b3f7196", + "status": "translated" } }, "addNewTranslationTooltip": { @@ -297,6 +582,21 @@ "checksum": "302876a521da0e33b18705d2f776008c", "baseChecksum": "e26fd2bf951546994a81c53bc593e520", "status": "translated" + }, + "ru": { + "checksum": "e621eb5ad060a4a7d05465cc3c6c7096", + "baseChecksum": "e26fd2bf951546994a81c53bc593e520", + "status": "translated" + }, + "ja": { + "checksum": "2bbb8dcf1c9c55839402701666ef6888", + "baseChecksum": "e26fd2bf951546994a81c53bc593e520", + "status": "translated" + }, + "de": { + "checksum": "4781020826316a9ecbf4396f8c9e6b45", + "baseChecksum": "e26fd2bf951546994a81c53bc593e520", + "status": "translated" } }, "noTranslation": { @@ -312,6 +612,21 @@ "checksum": "d3492fb7d6874d46221bc3c6b6e54a8d", "baseChecksum": "2856a7719f0542b5e808fa7baa1d6c93", "status": "translated" + }, + "ru": { + "checksum": "f8b534beda4cc6ab2f67295048a56fea", + "baseChecksum": "2856a7719f0542b5e808fa7baa1d6c93", + "status": "translated" + }, + "ja": { + "checksum": "bc42db0a02f61c45c64c3a56b158aa6b", + "baseChecksum": "2856a7719f0542b5e808fa7baa1d6c93", + "status": "translated" + }, + "de": { + "checksum": "be51d61fab92bba1ba2890b5a9ec6502", + "baseChecksum": "2856a7719f0542b5e808fa7baa1d6c93", + "status": "translated" } }, "commentPrefix": { @@ -327,6 +642,21 @@ "checksum": "c3b1fbaf8c6b65e312a0e4920cc19b42", "baseChecksum": "240f3031f25601fa128bd4e15f0a37de", "status": "translated" + }, + "ru": { + "checksum": "499b9bd346e02b97baf20bb8f649cb37", + "baseChecksum": "240f3031f25601fa128bd4e15f0a37de", + "status": "translated" + }, + "ja": { + "checksum": "ed114a48e97e3ec41713209a0c66b9f8", + "baseChecksum": "240f3031f25601fa128bd4e15f0a37de", + "status": "translated" + }, + "de": { + "checksum": "4b097715317ccc915985b3527a068f3a", + "baseChecksum": "240f3031f25601fa128bd4e15f0a37de", + "status": "translated" } }, "toggleExpansion": { @@ -342,6 +672,21 @@ "checksum": "6c0219acbdc6307898118a325d8ff138", "baseChecksum": "a600b0cbba3359d934a659341e5b727b", "status": "translated" + }, + "ru": { + "checksum": "73ccd74271a9e6b138f4b699c3bf78d8", + "baseChecksum": "a600b0cbba3359d934a659341e5b727b", + "status": "translated" + }, + "ja": { + "checksum": "40786f814610f633f1b322b0caf01025", + "baseChecksum": "a600b0cbba3359d934a659341e5b727b", + "status": "translated" + }, + "de": { + "checksum": "0481a68c4e2090ddb31725d7542181d9", + "baseChecksum": "a600b0cbba3359d934a659341e5b727b", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/translationEditor/commentConfirm/resource_entries.json b/apps/tracker/src/i18n/browser/translationEditor/commentConfirm/resource_entries.json index 10d31869..314cd710 100644 --- a/apps/tracker/src/i18n/browser/translationEditor/commentConfirm/resource_entries.json +++ b/apps/tracker/src/i18n/browser/translationEditor/commentConfirm/resource_entries.json @@ -4,27 +4,39 @@ "comment": "Dialog title when submitting without a comment", "tags": ["browser"], "es": "Sin comentarios añadidos", - "fr-ca": "Aucun commentaire ajouté" + "fr-ca": "Aucun commentaire ajouté", + "ru": "Комментарий не добавлен", + "ja": "コメントは追加されていません", + "de": "Kein Kommentar hinzugefügt" }, "message": { "source": "Comments help other translators understand context. Are you sure you want to save without a comment?", "comment": "Confirmation message about missing comment", "tags": ["browser"], "es": "Los comentarios ayudan a otros traductores a comprender el contexto. ¿Seguro que quieres guardar sin comentarios?", - "fr-ca": "Les commentaires aident les autres traducteurs à comprendre le contexte. Voulez-vous vraiment enregistrer sans commentaire ?" + "fr-ca": "Les commentaires aident les autres traducteurs à comprendre le contexte. Voulez-vous vraiment enregistrer sans commentaire ?", + "ru": "Комментарии помогают другим переводчикам понять контекст. Вы уверены, что хотите сохранить документ без комментария?", + "ja": "コメントは他の翻訳者が文脈を理解するのに役立ちます。コメントなしで保存してもよろしいですか?", + "de": "Kommentare helfen anderen Übersetzern, den Kontext zu verstehen. Möchten Sie die Datei wirklich ohne Kommentar speichern?" }, "saveAnyway": { "source": "Save Anyway", "comment": "Button to proceed without comment", "tags": ["browser"], "es": "Guardar de todos modos", - "fr-ca": "Sauvegarder quand même" + "fr-ca": "Sauvegarder quand même", + "ru": "В любом случае сохранить", + "ja": "とにかく保存する", + "de": "Trotzdem speichern" }, "addComment": { "source": "Add Comment", "comment": "Button to go back and add a comment", "tags": ["browser"], "es": "Añadir comentario", - "fr-ca": "Ajouter un commentaire" + "fr-ca": "Ajouter un commentaire", + "ru": "Добавить комментарий", + "ja": "コメントを追加", + "de": "Kommentar hinzufügen" } } diff --git a/apps/tracker/src/i18n/browser/translationEditor/commentConfirm/tracker_meta.json b/apps/tracker/src/i18n/browser/translationEditor/commentConfirm/tracker_meta.json index 9d37b1a0..8b950a64 100644 --- a/apps/tracker/src/i18n/browser/translationEditor/commentConfirm/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/translationEditor/commentConfirm/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "c64a94c7605203f3cd268369aef501db", "baseChecksum": "530d98327e030fcb737f5821d32684f4", "status": "translated" + }, + "ru": { + "checksum": "2c3a45454b973f06cd5ebdf1959dae25", + "baseChecksum": "530d98327e030fcb737f5821d32684f4", + "status": "translated" + }, + "ja": { + "checksum": "8422c999f7ca634b16fb41454b36cfca", + "baseChecksum": "530d98327e030fcb737f5821d32684f4", + "status": "translated" + }, + "de": { + "checksum": "43cf190ade83de9432e03faf60026840", + "baseChecksum": "530d98327e030fcb737f5821d32684f4", + "status": "translated" } }, "message": { @@ -27,6 +42,21 @@ "checksum": "d589cdbb0b05a9a0180e3047221fdcbd", "baseChecksum": "5bd6562c61ffbb16b723bdaad497a7fe", "status": "translated" + }, + "ru": { + "checksum": "a891cc739cae53e981ea9a4823e6fcc1", + "baseChecksum": "5bd6562c61ffbb16b723bdaad497a7fe", + "status": "translated" + }, + "ja": { + "checksum": "2d5750a29bf55220f1e6685c2bd435f4", + "baseChecksum": "5bd6562c61ffbb16b723bdaad497a7fe", + "status": "translated" + }, + "de": { + "checksum": "5e9bd3c52ba462d8eb541d1fef01185a", + "baseChecksum": "5bd6562c61ffbb16b723bdaad497a7fe", + "status": "translated" } }, "saveAnyway": { @@ -42,6 +72,21 @@ "checksum": "4d784e8a28ffb470384928bac41e1ad6", "baseChecksum": "8e4d177015b856fc0864fea051e6ad57", "status": "translated" + }, + "ru": { + "checksum": "68025402bb82a18da19a787c6f7b138b", + "baseChecksum": "8e4d177015b856fc0864fea051e6ad57", + "status": "translated" + }, + "ja": { + "checksum": "0ceece09d9645df4510d92c685f5ad61", + "baseChecksum": "8e4d177015b856fc0864fea051e6ad57", + "status": "translated" + }, + "de": { + "checksum": "71af06e4f7eb515af230b767ac31469c", + "baseChecksum": "8e4d177015b856fc0864fea051e6ad57", + "status": "translated" } }, "addComment": { @@ -57,6 +102,21 @@ "checksum": "04979267671e33bcd261434689879386", "baseChecksum": "a508cd6ee07b35ea8efdf98d6520ce83", "status": "translated" + }, + "ru": { + "checksum": "86571d3b73c9fcf90635997b576007bb", + "baseChecksum": "a508cd6ee07b35ea8efdf98d6520ce83", + "status": "translated" + }, + "ja": { + "checksum": "49c9ea90a9ab1f73d3cd2c0626430d9a", + "baseChecksum": "a508cd6ee07b35ea8efdf98d6520ce83", + "status": "translated" + }, + "de": { + "checksum": "e1ac8fee45f0845f898ea93429d147fd", + "baseChecksum": "a508cd6ee07b35ea8efdf98d6520ce83", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/translationEditor/conflict/resource_entries.json b/apps/tracker/src/i18n/browser/translationEditor/conflict/resource_entries.json index e4fcf755..3602db98 100644 --- a/apps/tracker/src/i18n/browser/translationEditor/conflict/resource_entries.json +++ b/apps/tracker/src/i18n/browser/translationEditor/conflict/resource_entries.json @@ -4,27 +4,39 @@ "comment": "Dialog title when key conflicts with existing resource", "tags": ["browser"], "es": "La clave de traducción ya existe", - "fr-ca": "La clé de traduction existe déjà." + "fr-ca": "La clé de traduction existe déjà.", + "ru": "Ключ перевода уже существует", + "ja": "翻訳キーは既に存在します", + "de": "Übersetzungsschlüssel existiert bereits" }, "messageX": { "source": "The translation key \"{key}\" already exists in this collection. Would you like to edit the existing translation or choose a different key?", "comment": "Conflict dialog message with the conflicting key name", "tags": ["browser"], "es": "La clave de traducción \"{key}\" ya existe en esta colección. ¿Desea editar la traducción existente o elegir una clave diferente?", - "fr-ca": "La clé de traduction « {key} » existe déjà dans cette collection. Souhaitez-vous modifier la traduction existante ou choisir une autre clé ?" + "fr-ca": "La clé de traduction « {key} » existe déjà dans cette collection. Souhaitez-vous modifier la traduction existante ou choisir une autre clé ?", + "ru": "Ключ перевода \"{key}\" уже существует в этой коллекции. Хотите отредактировать существующий перевод или выбрать другой ключ?", + "ja": "翻訳キー「{key}」は既にこのコレクションに存在します。既存の翻訳を編集しますか、それとも別のキーを選択しますか?", + "de": "Der Übersetzungsschlüssel \"{key}\" ist in dieser Sammlung bereits vorhanden. Möchten Sie die bestehende Übersetzung bearbeiten oder einen anderen Schlüssel auswählen?" }, "editExisting": { "source": "Edit Existing", "comment": "Button to open the existing resource for editing", "tags": ["browser"], "es": "Editar existente", - "fr-ca": "Modifier l'existant" + "fr-ca": "Modifier l'existant", + "ru": "Редактировать существующий", + "ja": "既存のものを編集する", + "de": "Vorhandenen bearbeiten" }, "chooseDifferentKey": { "source": "Choose Different Key", "comment": "Button to go back and pick a different key", "tags": ["browser"], "es": "Elija una clave diferente", - "fr-ca": "Choisir une autre clé" + "fr-ca": "Choisir une autre clé", + "ru": "Выберите другой ключ", + "ja": "別のキーを選択してください", + "de": "Wählen Sie eine andere Taste" } } diff --git a/apps/tracker/src/i18n/browser/translationEditor/conflict/tracker_meta.json b/apps/tracker/src/i18n/browser/translationEditor/conflict/tracker_meta.json index 06d737e3..a2197203 100644 --- a/apps/tracker/src/i18n/browser/translationEditor/conflict/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/translationEditor/conflict/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "3f960e9f62b448593af4f4e6268f37eb", "baseChecksum": "045a806cdff0da04ef93312480a9934e", "status": "translated" + }, + "ru": { + "checksum": "c63d79c96c3134a0f4ba01d0249ff134", + "baseChecksum": "045a806cdff0da04ef93312480a9934e", + "status": "translated" + }, + "ja": { + "checksum": "eae01e38b9130eda454eee100fa18b6d", + "baseChecksum": "045a806cdff0da04ef93312480a9934e", + "status": "translated" + }, + "de": { + "checksum": "71b9781d6fef7ddabc479f3e13cb9c02", + "baseChecksum": "045a806cdff0da04ef93312480a9934e", + "status": "translated" } }, "messageX": { @@ -27,6 +42,21 @@ "checksum": "1228373b337d25fe96d944ad0103a4bc", "baseChecksum": "765a0106f27fce3620418e6a5afece18", "status": "stale" + }, + "ru": { + "checksum": "5dcee4e9669d158cef1d3bcfbe2d985c", + "baseChecksum": "765a0106f27fce3620418e6a5afece18", + "status": "translated" + }, + "ja": { + "checksum": "d4ed5eccd890b1df12a412e06953ac19", + "baseChecksum": "765a0106f27fce3620418e6a5afece18", + "status": "translated" + }, + "de": { + "checksum": "e812e78f3e137e2471b0396575ec61e1", + "baseChecksum": "765a0106f27fce3620418e6a5afece18", + "status": "translated" } }, "editExisting": { @@ -42,6 +72,21 @@ "checksum": "acc8b3c3f491614fb6a457067a5f07c0", "baseChecksum": "b44e9a9caec20a27fc82ac2a7574639a", "status": "translated" + }, + "ru": { + "checksum": "c96691855499f791f0427d9b91503d4b", + "baseChecksum": "b44e9a9caec20a27fc82ac2a7574639a", + "status": "translated" + }, + "ja": { + "checksum": "85ca194852efd9073f380df903e2f608", + "baseChecksum": "b44e9a9caec20a27fc82ac2a7574639a", + "status": "translated" + }, + "de": { + "checksum": "5a55ef33a6234ff36d6a386da6ab2336", + "baseChecksum": "b44e9a9caec20a27fc82ac2a7574639a", + "status": "translated" } }, "chooseDifferentKey": { @@ -57,6 +102,21 @@ "checksum": "d5805e73f15774b7eaa44003b35e3e30", "baseChecksum": "5275ecd41038dd5cab36ac1d387e95aa", "status": "translated" + }, + "ru": { + "checksum": "7dec38b22dfbcb03964b55056be92d57", + "baseChecksum": "5275ecd41038dd5cab36ac1d387e95aa", + "status": "translated" + }, + "ja": { + "checksum": "391ea33afe4c7850f21ab4aab09ff836", + "baseChecksum": "5275ecd41038dd5cab36ac1d387e95aa", + "status": "translated" + }, + "de": { + "checksum": "b15777d65f74a76f6e45fe581a06a942", + "baseChecksum": "5275ecd41038dd5cab36ac1d387e95aa", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/translationEditor/error/resource_entries.json b/apps/tracker/src/i18n/browser/translationEditor/error/resource_entries.json index 91109188..b72cbd4d 100644 --- a/apps/tracker/src/i18n/browser/translationEditor/error/resource_entries.json +++ b/apps/tracker/src/i18n/browser/translationEditor/error/resource_entries.json @@ -4,48 +4,69 @@ "comment": "Error when resource data is unavailable during edit", "tags": ["browser"], "es": "No se puede actualizar: faltan datos del recurso", - "fr-ca": "Impossible de mettre à jour : les données de ressources sont manquantes." + "fr-ca": "Impossible de mettre à jour : les données de ressources sont manquantes.", + "ru": "Невозможно обновить: отсутствуют данные ресурса.", + "ja": "更新できません: リソースデータが不足しています", + "de": "Aktualisierung fehlgeschlagen: Ressourcendaten fehlen" }, "keyRenamingNotSupported": { "source": "Key renaming is not yet supported. Please use the same key or create a new resource.", "comment": "Error when user tries to change resource key", "tags": ["browser"], "es": "Aún no se admite el cambio de nombre de clave. Utilice la misma clave o cree un nuevo recurso.", - "fr-ca": "Le renommage des clés n'est pas encore pris en charge. Veuillez utiliser la même clé ou créer une nouvelle ressource." + "fr-ca": "Le renommage des clés n'est pas encore pris en charge. Veuillez utiliser la même clé ou créer une nouvelle ressource.", + "ru": "Функция переименования ключей пока не поддерживается. Пожалуйста, используйте тот же ключ или создайте новый ресурс.", + "ja": "キー名の変更はまだサポートされていません。同じキーを使用するか、新しいリソースを作成してください。", + "de": "Das Umbenennen von Schlüsseln wird noch nicht unterstützt. Bitte verwenden Sie denselben Schlüssel oder erstellen Sie eine neue Ressource." }, "notFound": { "source": "Resource not found. It may have been deleted.", "comment": "Error when resource no longer exists on server", "tags": ["browser"], "es": "Recurso no encontrado. Es posible que se haya eliminado.", - "fr-ca": "Ressource introuvable. Elle a peut-être été supprimée." + "fr-ca": "Ressource introuvable. Elle a peut-être été supprimée.", + "ru": "Ресурс не найден. Возможно, он был удален.", + "ja": "リソースが見つかりません。削除された可能性があります。", + "de": "Ressource nicht gefunden. Sie wurde möglicherweise gelöscht." }, "invalidRequest": { "source": "Invalid request", "comment": "Fallback error message for 400 status responses", "tags": ["browser"], "es": "Solicitud no válida", - "fr-ca": "Requête invalide" + "fr-ca": "Requête invalide", + "ru": "Неверный запрос", + "ja": "無効なリクエスト", + "de": "Ungültige Anfrage" }, "createFailed": { "source": "Failed to create translation", "comment": "Fallback error when resource creation fails", "tags": ["browser"], "es": "No se pudo crear la traducción", - "fr-ca": "Échec de la traduction" + "fr-ca": "Échec de la traduction", + "ru": "Не удалось создать перевод", + "ja": "翻訳の作成に失敗しました", + "de": "Übersetzung konnte nicht erstellt werden" }, "updateFailed": { "source": "Failed to update translation", "comment": "Fallback error when resource update fails", "tags": ["browser"], "es": "No se pudo actualizar la traducción", - "fr-ca": "Échec de la mise à jour de la traduction" + "fr-ca": "Échec de la mise à jour de la traduction", + "ru": "Не удалось обновить перевод", + "ja": "翻訳の更新に失敗しました", + "de": "Übersetzung konnte nicht aktualisiert werden" }, "unexpected": { "source": "An unexpected error occurred", "comment": "Fallback error for non-HTTP errors", "tags": ["browser"], "es": "Se produjo un error inesperado", - "fr-ca": "Une erreur inattendue s'est produite." + "fr-ca": "Une erreur inattendue s'est produite.", + "ru": "Произошла непредвиденная ошибка.", + "ja": "予期せぬエラーが発生しました", + "de": "Es ist ein unerwarteter Fehler aufgetreten." } } diff --git a/apps/tracker/src/i18n/browser/translationEditor/error/tracker_meta.json b/apps/tracker/src/i18n/browser/translationEditor/error/tracker_meta.json index c4d74183..a9facfc7 100644 --- a/apps/tracker/src/i18n/browser/translationEditor/error/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/translationEditor/error/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "60a05d3a9bc1a83a449f3397e81b54a2", "baseChecksum": "2f84b28f0c1490dbd9252e71e4031cf2", "status": "translated" + }, + "ru": { + "checksum": "f367dff2a5b4ba833696a76796dea8bd", + "baseChecksum": "2f84b28f0c1490dbd9252e71e4031cf2", + "status": "translated" + }, + "ja": { + "checksum": "d5d568690e6d54e50b191a46ec907e6e", + "baseChecksum": "2f84b28f0c1490dbd9252e71e4031cf2", + "status": "translated" + }, + "de": { + "checksum": "ca6263f4a644ae0efeb8a9c13c4dff70", + "baseChecksum": "2f84b28f0c1490dbd9252e71e4031cf2", + "status": "translated" } }, "keyRenamingNotSupported": { @@ -27,6 +42,21 @@ "checksum": "90d61297c3b4fbac388c4be2b71bcc64", "baseChecksum": "575ba68788d69e22ad6e2d4ecdb01755", "status": "translated" + }, + "ru": { + "checksum": "2bb377f62e8cd28ed1f101cf11565bb0", + "baseChecksum": "575ba68788d69e22ad6e2d4ecdb01755", + "status": "translated" + }, + "ja": { + "checksum": "fb129524f433be0cb204402f3e85e9e1", + "baseChecksum": "575ba68788d69e22ad6e2d4ecdb01755", + "status": "translated" + }, + "de": { + "checksum": "440299bfba3af128ac1d34ee956a2488", + "baseChecksum": "575ba68788d69e22ad6e2d4ecdb01755", + "status": "translated" } }, "notFound": { @@ -42,6 +72,21 @@ "checksum": "31f68ee8d39879dc72fbc7a13727fa91", "baseChecksum": "a7e38d0533724516bbacee18834f67a5", "status": "translated" + }, + "ru": { + "checksum": "ff9cd65e3847be6d65913357ff266b62", + "baseChecksum": "a7e38d0533724516bbacee18834f67a5", + "status": "translated" + }, + "ja": { + "checksum": "8dba597c97c3e2d906f1a68252f022b8", + "baseChecksum": "a7e38d0533724516bbacee18834f67a5", + "status": "translated" + }, + "de": { + "checksum": "ffef463ed13cd984c9ad3ff239ddf334", + "baseChecksum": "a7e38d0533724516bbacee18834f67a5", + "status": "translated" } }, "invalidRequest": { @@ -57,6 +102,21 @@ "checksum": "d6ee1ca377f0f08728472801722d1ad5", "baseChecksum": "446b416d535ed3f547fcd653dc11d49c", "status": "translated" + }, + "ru": { + "checksum": "343c7ad78b07f5457b637432b7ff6bda", + "baseChecksum": "446b416d535ed3f547fcd653dc11d49c", + "status": "translated" + }, + "ja": { + "checksum": "202965d477812eed4ee85904d9312b62", + "baseChecksum": "446b416d535ed3f547fcd653dc11d49c", + "status": "translated" + }, + "de": { + "checksum": "ace9e949ddf27fcc22a226a672f51c6f", + "baseChecksum": "446b416d535ed3f547fcd653dc11d49c", + "status": "translated" } }, "createFailed": { @@ -72,6 +132,21 @@ "checksum": "fa7979919d970f5fd2df5d63a36735d9", "baseChecksum": "20a64455184899c3fb2e93b4566c8860", "status": "translated" + }, + "ru": { + "checksum": "3b7de41d823bcb5109f394af407c9d21", + "baseChecksum": "20a64455184899c3fb2e93b4566c8860", + "status": "translated" + }, + "ja": { + "checksum": "b163306edd3646085650b155d84c7284", + "baseChecksum": "20a64455184899c3fb2e93b4566c8860", + "status": "translated" + }, + "de": { + "checksum": "e81599470a34eba2f73342a116ee4b84", + "baseChecksum": "20a64455184899c3fb2e93b4566c8860", + "status": "translated" } }, "updateFailed": { @@ -87,6 +162,21 @@ "checksum": "a63fdd90ff3ce2dbfa649a37ee6e503d", "baseChecksum": "b3991113a051bbeb759a923bc636ad8d", "status": "translated" + }, + "ru": { + "checksum": "5108d70d09cb4b6066e975ce887c6c04", + "baseChecksum": "b3991113a051bbeb759a923bc636ad8d", + "status": "translated" + }, + "ja": { + "checksum": "5e669e72e0db8ae03175cf1edb5a501e", + "baseChecksum": "b3991113a051bbeb759a923bc636ad8d", + "status": "translated" + }, + "de": { + "checksum": "2713d38910a9ee049868d31c04364897", + "baseChecksum": "b3991113a051bbeb759a923bc636ad8d", + "status": "translated" } }, "unexpected": { @@ -102,6 +192,21 @@ "checksum": "1493006d4d13050b985dce812a2b7b15", "baseChecksum": "9789e322478c6f2d59e93d020808642a", "status": "translated" + }, + "ru": { + "checksum": "660b970b7d6a7be830945cf28709dd59", + "baseChecksum": "9789e322478c6f2d59e93d020808642a", + "status": "translated" + }, + "ja": { + "checksum": "08b714614a930ce585efec212bcc5581", + "baseChecksum": "9789e322478c6f2d59e93d020808642a", + "status": "translated" + }, + "de": { + "checksum": "e0f85585eb6819ac437502fe5c29d871", + "baseChecksum": "9789e322478c6f2d59e93d020808642a", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/translationEditor/resource_entries.json b/apps/tracker/src/i18n/browser/translationEditor/resource_entries.json index 5e5d30e9..dcd7fa9c 100644 --- a/apps/tracker/src/i18n/browser/translationEditor/resource_entries.json +++ b/apps/tracker/src/i18n/browser/translationEditor/resource_entries.json @@ -4,174 +4,249 @@ "comment": "Aria-label for close button on translation editor dialog", "tags": ["browser"], "es": "Cerrar diálogo", - "fr-ca": "Fermer la boîte de dialogue" + "fr-ca": "Fermer la boîte de dialogue", + "ru": "Закрыть диалог", + "ja": "ダイアログを閉じる", + "de": "Dialog schließen" }, "translationKey": { "source": "Translation Key", "comment": "Label for the translation key input field", "tags": ["browser"], "es": "Clave de traducción", - "fr-ca": "Clé de traduction" + "fr-ca": "Clé de traduction", + "ru": "Ключ перевода", + "ja": "翻訳キー", + "de": "Übersetzungsschlüssel" }, "keyHint": { "source": "Use only letters, numbers, underscores, and hyphens", "comment": "Hint text below translation key input", "tags": ["browser"], "es": "Utilice únicamente letras, números, guiones bajos y guiones.", - "fr-ca": "Utilisez seulement des lettres, des chiffres, des traits de soulignement et des tirets." + "fr-ca": "Utilisez seulement des lettres, des chiffres, des traits de soulignement et des tirets.", + "ru": "Используйте только буквы, цифры, подчеркивания и дефисы.", + "ja": "文字、数字、アンダースコア、ハイフンのみを使用してください。", + "de": "Verwenden Sie nur Buchstaben, Zahlen, Unterstriche und Bindestriche." }, "baseBadge": { "source": "Base", "comment": "Badge label indicating the base locale", "tags": ["browser"], "es": "Base", - "fr-ca": "Base" + "fr-ca": "Base", + "ru": "База", + "ja": "ベース", + "de": "Base" }, "locationLabel": { "source": "Location:", "comment": "Label prefix for the current folder location in the translation editor dialog", "tags": ["browser"], "es": "Ubicación:", - "fr-ca": "Emplacement :" + "fr-ca": "Emplacement :", + "ru": "Расположение:", + "ja": "位置:", + "de": "Standort:" }, "locationTabHint": { "source": "Choose a different folder for this translation resource.", "comment": "Hint text shown at the top of the Change Location tab in the translation editor", "tags": ["browser"], "es": "Elija una carpeta diferente para este recurso de traducción.", - "fr-ca": "Choisissez un autre dossier pour cette ressource de traduction." + "fr-ca": "Choisissez un autre dossier pour cette ressource de traduction.", + "ru": "Выберите другую папку для этого ресурса перевода.", + "ja": "この翻訳リソースの保存先フォルダを別のフォルダに選択してください。", + "de": "Wählen Sie einen anderen Ordner für diese Übersetzungsressource." }, "localeTranslationX": { "source": "{locale} Translation", "comment": "Label for locale translation input field, locale is uppercased locale code", "tags": ["browser"], "es": "{locale} Traducción", - "fr-ca": "{locale} Traduction" + "fr-ca": "{locale} Traduction", + "ru": "{locale} Перевод", + "ja": "{locale} 翻訳", + "de": "{locale} Übersetzung" }, "enterTranslationX": { "source": "Enter {locale} translation...", "comment": "Placeholder for locale translation input field", "tags": ["browser"], "es": "Ingrese la traducción de {locale}...", - "fr-ca": "Entrez la traduction {locale}..." + "fr-ca": "Entrez la traduction {locale}...", + "ru": "Введите {locale} перевод...", + "ja": "{locale} 翻訳を入力してください...", + "de": "Geben Sie die Übersetzung {locale} ein..." }, "baseValueRequired": { "source": "Base translation is required", "comment": "Error shown when base translation value is empty", "tags": ["browser"], "es": "Se requiere traducción base", - "fr-ca": "La traduction de base est requise" + "fr-ca": "La traduction de base est requise", + "ru": "Требуется базовый перевод.", + "ja": "基本翻訳が必要です", + "de": "Eine Basisübersetzung ist erforderlich." }, "commentLabel": { "source": "Comment (Optional)", "comment": "Label for optional comment field", "tags": ["browser"], "es": "Comentario (opcional)", - "fr-ca": "Commentaire (facultatif)" + "fr-ca": "Commentaire (facultatif)", + "ru": "Комментарий (необязательно)", + "ja": "コメント(任意)", + "de": "Kommentar (optional)" }, "commentPlaceholder": { "source": "Add context for translators...", "comment": "Placeholder for comment input field", "tags": ["browser"], "es": "Añadir contexto para los traductores...", - "fr-ca": "Ajouter du contexte pour les traducteurs..." + "fr-ca": "Ajouter du contexte pour les traducteurs...", + "ru": "Добавьте контекст для переводчиков...", + "ja": "翻訳者向けに背景情報を追加してください...", + "de": "Kontext für Übersetzer hinzufügen..." }, "commentHint": { "source": "Provide context or instructions for translators", "comment": "Hint text below comment field", "tags": ["browser"], "es": "Proporcionar contexto o instrucciones para los traductores", - "fr-ca": "Fournir un contexte ou des instructions aux traducteurs" + "fr-ca": "Fournir un contexte ou des instructions aux traducteurs", + "ru": "Предоставьте контекст или инструкции для переводчиков.", + "ja": "翻訳者向けに背景情報や指示を提供する", + "de": "Geben Sie Kontext oder Anweisungen für die Übersetzer an." }, "otherLocalesToggleX": { "source": "Add translations for other locales ({count} available)", "comment": "Toggle label showing number of additional locales", "tags": ["browser"], "es": "Agregar traducciones para otras configuraciones regionales ({count} disponible)", - "fr-ca": "Ajouter des traductions pour d'autres langues ({count} disponibles)" + "fr-ca": "Ajouter des traductions pour d'autres langues ({count} disponibles)", + "ru": "Добавить переводы для других языковых версий ({count} доступны)", + "ja": "他のロケールの翻訳を追加してください({count} が利用可能です)", + "de": "Übersetzungen für weitere Gebietsschemas hinzufügen ({count} verfügbar)" }, "status": { "source": "Status", "comment": "Label for translation status dropdown", "tags": ["browser"], "es": "Estado", - "fr-ca": "Statut" + "fr-ca": "Statut", + "ru": "Статус", + "ja": "状態", + "de": "Status" }, "saving": { "source": "Saving...", "comment": "Button text shown while form is submitting", "tags": ["browser"], "es": "Ahorro...", - "fr-ca": "Économie..." + "fr-ca": "Économie...", + "ru": "Сохранение...", + "ja": "保存中...", + "de": "Speichern..." }, "editTitle": { "source": "Edit Translation", "comment": "Dialog title when editing an existing translation", "tags": ["browser"], "es": "Editar traducción", - "fr-ca": "Modifier la traduction" + "fr-ca": "Modifier la traduction", + "ru": "Редактировать перевод", + "ja": "翻訳を編集する", + "de": "Übersetzung bearbeiten" }, "createTitle": { "source": "Create Translation", "comment": "Dialog title when creating a new translation", "tags": ["browser"], "es": "Crear traducción", - "fr-ca": "Créer une traduction" + "fr-ca": "Créer une traduction", + "ru": "Создать перевод", + "ja": "翻訳を作成する", + "de": "Übersetzung erstellen" }, "editSubtitle": { "source": "Update translation values and metadata", "comment": "Dialog subtitle in edit mode", "tags": ["browser"], "es": "Actualizar los valores de traducción y los metadatos", - "fr-ca": "Mise à jour des valeurs de traduction et des métadonnées" + "fr-ca": "Mise à jour des valeurs de traduction et des métadonnées", + "ru": "Обновите значения перевода и метаданные.", + "ja": "翻訳値とメタデータを更新する", + "de": "Aktualisierung der Übersetzungswerte und Metadaten" }, "createSubtitle": { "source": "Add a new translation entry to your collection", "comment": "Dialog subtitle in create mode", "tags": ["browser"], "es": "Añade una nueva entrada de traducción a tu colección", - "fr-ca": "Ajoutez une nouvelle entrée de traduction à votre collection" + "fr-ca": "Ajoutez une nouvelle entrée de traduction à votre collection", + "ru": "Добавьте новую запись о переводе в свою коллекцию.", + "ja": "コレクションに新しい翻訳エントリを追加する", + "de": "Füge deiner Sammlung einen neuen Übersetzungseintrag hinzu." }, "updateButton": { "source": "Update Translation", "comment": "Submit button label in edit mode", "tags": ["browser"], "es": "Actualizar traducción", - "fr-ca": "Mise à jour de la traduction" + "fr-ca": "Mise à jour de la traduction", + "ru": "Обновить перевод", + "ja": "翻訳を更新", + "de": "Übersetzung aktualisieren" }, "saveButton": { "source": "Save Translation", "comment": "Submit button label in create mode", "tags": ["browser"], "es": "Guardar traducción", - "fr-ca": "Enregistrer la traduction" + "fr-ca": "Enregistrer la traduction", + "ru": "Сохранить перевод", + "ja": "翻訳を保存", + "de": "Übersetzung speichern" }, "keyCopied": { "source": "Similar resource key copied", "comment": "Snackbar message after copying a similar resource key", "tags": ["browser"], "es": "Clave de recurso similar copiada", - "fr-ca": "Clé de ressource similaire copiée" + "fr-ca": "Clé de ressource similaire copiée", + "ru": "Аналогичный ключ ресурса скопирован.", + "ja": "同様のリソースキーがコピーされました", + "de": "Ähnlicher Ressourcenschlüssel kopiert" }, "copyFailed": { "source": "Failed to copy", "comment": "Snackbar message when clipboard copy fails", "tags": ["browser"], "es": "No se pudo copiar", - "fr-ca": "Échec de la copie" + "fr-ca": "Échec de la copie", + "ru": "Не удалось скопировать", + "ja": "コピーに失敗しました", + "de": "Kopiervorgang fehlgeschlagen" }, "keyRequired": { "source": "Translation key is required", "comment": "Validation error for empty key field", "tags": ["browser"], "es": "Se requiere clave de traducción", - "fr-ca": "Une clé de traduction est requise." + "fr-ca": "Une clé de traduction est requise.", + "ru": "Требуется ключ перевода", + "ja": "翻訳キーが必要です", + "de": "Übersetzungsschlüssel erforderlich" }, "keyPatternError": { "source": "Only letters, numbers, underscores, and hyphens allowed", "comment": "Validation error for invalid key characters", "tags": ["browser"], "es": "Solo se permiten letras, números, guiones bajos y guiones.", - "fr-ca": "Seules les lettres, les chiffres, les traits de soulignement et les tirets sont autorisés." + "fr-ca": "Seules les lettres, les chiffres, les traits de soulignement et les tirets sont autorisés.", + "ru": "Разрешаются только буквы, цифры, подчеркивания и дефисы.", + "ja": "使用できる文字は、英字、数字、アンダースコア、ハイフンのみです。", + "de": "Nur Buchstaben, Zahlen, Unterstriche und Bindestriche sind erlaubt." } } diff --git a/apps/tracker/src/i18n/browser/translationEditor/tab/resource_entries.json b/apps/tracker/src/i18n/browser/translationEditor/tab/resource_entries.json index 7913089f..6a94861f 100644 --- a/apps/tracker/src/i18n/browser/translationEditor/tab/resource_entries.json +++ b/apps/tracker/src/i18n/browser/translationEditor/tab/resource_entries.json @@ -4,20 +4,29 @@ "comment": "Tab label for the base translation info section in the editor dialog", "tags": ["browser"], "es": "Información básica", - "fr-ca": "Informations de base" + "fr-ca": "Informations de base", + "ru": "Базовая информация", + "ja": "基本情報", + "de": "Basisinformationen" }, "changeLocation": { "source": "Change Location", "comment": "Tab label for the change location section in the editor dialog", "tags": ["browser"], "es": "Cambiar ubicación", - "fr-ca": "Changer d'emplacement" + "fr-ca": "Changer d'emplacement", + "ru": "Изменить местоположение", + "ja": "場所を変更する", + "de": "Standort ändern" }, "otherLocales": { "source": "Other Locales", "comment": "Tab label for the other locales section in the editor dialog", "tags": ["browser"], "es": "Otros lugares", - "fr-ca": "Autres localités" + "fr-ca": "Autres localités", + "ru": "Другие населенные пункты", + "ja": "その他の地域", + "de": "Andere Orte" } } diff --git a/apps/tracker/src/i18n/browser/translationEditor/tab/tracker_meta.json b/apps/tracker/src/i18n/browser/translationEditor/tab/tracker_meta.json index 46a15ee8..6f9574b9 100644 --- a/apps/tracker/src/i18n/browser/translationEditor/tab/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/translationEditor/tab/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "e7c2ebf83638051fcfc3bffd2697e2ec", "baseChecksum": "f0c1c6dcc3cd228eb523f5809d39878e", "status": "translated" + }, + "ru": { + "checksum": "1d0d6fe6f6c7d24f49c30c25806eeb00", + "baseChecksum": "f0c1c6dcc3cd228eb523f5809d39878e", + "status": "translated" + }, + "ja": { + "checksum": "1ea1bc9ca57838426391b54659ec0235", + "baseChecksum": "f0c1c6dcc3cd228eb523f5809d39878e", + "status": "translated" + }, + "de": { + "checksum": "9ea673b3bd066bb5b0cb547eeaed96b2", + "baseChecksum": "f0c1c6dcc3cd228eb523f5809d39878e", + "status": "translated" } }, "changeLocation": { @@ -27,6 +42,21 @@ "checksum": "dc49addffb6da2de09e5a3fa596dcdfb", "baseChecksum": "6dd495f1c2ae29c8e9a6c4405f18e22e", "status": "translated" + }, + "ru": { + "checksum": "86568c4f274d53ddbd5c0ca909838948", + "baseChecksum": "6dd495f1c2ae29c8e9a6c4405f18e22e", + "status": "translated" + }, + "ja": { + "checksum": "1b8bf802cd4b26490f8d9ea9033c1b10", + "baseChecksum": "6dd495f1c2ae29c8e9a6c4405f18e22e", + "status": "translated" + }, + "de": { + "checksum": "37b9b091bf44c29f032ce905da6fd10f", + "baseChecksum": "6dd495f1c2ae29c8e9a6c4405f18e22e", + "status": "translated" } }, "otherLocales": { @@ -42,6 +72,21 @@ "checksum": "7d4be744a78b006182b35c9d056b566e", "baseChecksum": "aca1284fedfa7431bb8a9dc0b59fe6c6", "status": "translated" + }, + "ru": { + "checksum": "dae4ccfa3a748a5236612c9cb07dafac", + "baseChecksum": "aca1284fedfa7431bb8a9dc0b59fe6c6", + "status": "translated" + }, + "ja": { + "checksum": "5d191996e0ef3a0e2d45658ad517e8c1", + "baseChecksum": "aca1284fedfa7431bb8a9dc0b59fe6c6", + "status": "translated" + }, + "de": { + "checksum": "01a98b4b9cfdd78d96ce093d75f2efe6", + "baseChecksum": "aca1284fedfa7431bb8a9dc0b59fe6c6", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/translationEditor/tracker_meta.json b/apps/tracker/src/i18n/browser/translationEditor/tracker_meta.json index 1e2a109a..f6c20a7e 100644 --- a/apps/tracker/src/i18n/browser/translationEditor/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/translationEditor/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "1c5aa21be0d1004a8d54df134f55e348", "baseChecksum": "3c62b9dcfe365792b2fbb6e15dc82c80", "status": "translated" + }, + "ru": { + "checksum": "edff72b736205b30a294a01077e603af", + "baseChecksum": "3c62b9dcfe365792b2fbb6e15dc82c80", + "status": "translated" + }, + "ja": { + "checksum": "1198f0cc49d5b11d45c557bf14464b39", + "baseChecksum": "3c62b9dcfe365792b2fbb6e15dc82c80", + "status": "translated" + }, + "de": { + "checksum": "db286f6c48854edd1dc4d23d2621ab42", + "baseChecksum": "3c62b9dcfe365792b2fbb6e15dc82c80", + "status": "translated" } }, "translationKey": { @@ -27,6 +42,21 @@ "checksum": "92816cfd37b340742301c8b626623651", "baseChecksum": "482823ac52ef47827d3f18f259387366", "status": "translated" + }, + "ru": { + "checksum": "ad67eeaf79c8f882b6eb5cecf892322a", + "baseChecksum": "482823ac52ef47827d3f18f259387366", + "status": "translated" + }, + "ja": { + "checksum": "ad653346ad1c2bf5be218a569429dafa", + "baseChecksum": "482823ac52ef47827d3f18f259387366", + "status": "translated" + }, + "de": { + "checksum": "70cd2f99392575c8bc14d4cf46d9ef9a", + "baseChecksum": "482823ac52ef47827d3f18f259387366", + "status": "translated" } }, "keyHint": { @@ -42,6 +72,21 @@ "checksum": "b7b58d7abbfe1d258bea836ce70eb4ec", "baseChecksum": "a150213ebef4acd1123fc4f76b89141d", "status": "translated" + }, + "ru": { + "checksum": "a4309f56e3d6a57faf9ce6ba06d0af93", + "baseChecksum": "a150213ebef4acd1123fc4f76b89141d", + "status": "translated" + }, + "ja": { + "checksum": "838d654d1155ba342ba1f05995265764", + "baseChecksum": "a150213ebef4acd1123fc4f76b89141d", + "status": "translated" + }, + "de": { + "checksum": "9cff025ed420cce9d77d59fbec08f519", + "baseChecksum": "a150213ebef4acd1123fc4f76b89141d", + "status": "translated" } }, "baseBadge": { @@ -57,6 +102,21 @@ "checksum": "095a1b43effec73955e31e790438de49", "baseChecksum": "095a1b43effec73955e31e790438de49", "status": "translated" + }, + "ru": { + "checksum": "131622d25aebdc15c77aa76c29aaf3ee", + "baseChecksum": "095a1b43effec73955e31e790438de49", + "status": "translated" + }, + "ja": { + "checksum": "f8ccaf5926eb52b58809ea1a6481bba2", + "baseChecksum": "095a1b43effec73955e31e790438de49", + "status": "translated" + }, + "de": { + "checksum": "095a1b43effec73955e31e790438de49", + "baseChecksum": "095a1b43effec73955e31e790438de49", + "status": "translated" } }, "locationLabel": { @@ -72,6 +132,21 @@ "checksum": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6", "baseChecksum": "3a5b0a31626f29a78e12e995e0428fbb", "status": "translated" + }, + "ru": { + "checksum": "2be7ebd9f9cac1aa575397e3d0b12b01", + "baseChecksum": "3a5b0a31626f29a78e12e995e0428fbb", + "status": "translated" + }, + "ja": { + "checksum": "4c856befb87ffa52b70b527023d634d4", + "baseChecksum": "3a5b0a31626f29a78e12e995e0428fbb", + "status": "translated" + }, + "de": { + "checksum": "527d181f9e73d18b872ffea9d7af6544", + "baseChecksum": "3a5b0a31626f29a78e12e995e0428fbb", + "status": "translated" } }, "locationTabHint": { @@ -87,6 +162,21 @@ "checksum": "f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1", "baseChecksum": "d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9", "status": "translated" + }, + "ru": { + "checksum": "8278d26bbaa2462e777e00884338a749", + "baseChecksum": "d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9", + "status": "translated" + }, + "ja": { + "checksum": "16b48a57e9983e810366f033cd23422c", + "baseChecksum": "d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9", + "status": "translated" + }, + "de": { + "checksum": "6606f1a308e6297887adc1f1bb89f533", + "baseChecksum": "d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9", + "status": "translated" } }, "localeTranslationX": { @@ -102,6 +192,21 @@ "checksum": "6d2fd9fc703c835e836365104ce929c6", "baseChecksum": "06c8a0c2ef0476880f67ff4230e593b4", "status": "stale" + }, + "ru": { + "checksum": "820a9f699c16f046f7c80778834ec280", + "baseChecksum": "06c8a0c2ef0476880f67ff4230e593b4", + "status": "translated" + }, + "ja": { + "checksum": "5325b66f18cc4eb7baa08543e6e50008", + "baseChecksum": "06c8a0c2ef0476880f67ff4230e593b4", + "status": "translated" + }, + "de": { + "checksum": "490b3e6a8d4bcb11ea1a2b7d20e23d2b", + "baseChecksum": "06c8a0c2ef0476880f67ff4230e593b4", + "status": "translated" } }, "enterTranslationX": { @@ -117,6 +222,21 @@ "checksum": "9e1e2e4cd501aeb8196a6b20217bfd1d", "baseChecksum": "831af3e4fbd2ef1d6685bb25b9373509", "status": "stale" + }, + "ru": { + "checksum": "684070f154dc864269f0fc71bf86ca36", + "baseChecksum": "831af3e4fbd2ef1d6685bb25b9373509", + "status": "translated" + }, + "ja": { + "checksum": "f8df8394699f29d7ee64a8b57e40bb87", + "baseChecksum": "831af3e4fbd2ef1d6685bb25b9373509", + "status": "translated" + }, + "de": { + "checksum": "d984a7f236ba7c53301a18cef5170eda", + "baseChecksum": "831af3e4fbd2ef1d6685bb25b9373509", + "status": "translated" } }, "baseValueRequired": { @@ -132,6 +252,21 @@ "checksum": "37b5ac851fba5aa202b33019e04050e9", "baseChecksum": "51f066cb9c94152ad9096f4ceeaea6f3", "status": "translated" + }, + "ru": { + "checksum": "c2f37cd200003c3621956195646dcf09", + "baseChecksum": "51f066cb9c94152ad9096f4ceeaea6f3", + "status": "translated" + }, + "ja": { + "checksum": "e1f23a927b1fe254bb5ce734809ce3f9", + "baseChecksum": "51f066cb9c94152ad9096f4ceeaea6f3", + "status": "translated" + }, + "de": { + "checksum": "00c5e39e50c93a6dc0c29425b03d0fe4", + "baseChecksum": "51f066cb9c94152ad9096f4ceeaea6f3", + "status": "translated" } }, "commentLabel": { @@ -147,6 +282,21 @@ "checksum": "91a81b9ea21a3a27b3ad7732cd9466be", "baseChecksum": "3b45c3cd1875b697361bb48eee5c815d", "status": "translated" + }, + "ru": { + "checksum": "7d9f639233478a28d6bbedf16807a142", + "baseChecksum": "3b45c3cd1875b697361bb48eee5c815d", + "status": "translated" + }, + "ja": { + "checksum": "6386c833772eb5bbd9b351816b8609ba", + "baseChecksum": "3b45c3cd1875b697361bb48eee5c815d", + "status": "translated" + }, + "de": { + "checksum": "4cac0bd545991c45f894df028deeb506", + "baseChecksum": "3b45c3cd1875b697361bb48eee5c815d", + "status": "translated" } }, "commentPlaceholder": { @@ -162,6 +312,21 @@ "checksum": "cb30420c45287765b0c246e6b7b0f16f", "baseChecksum": "04627d882217f6ca0b5db70ab11645bd", "status": "translated" + }, + "ru": { + "checksum": "e045e9980e2ca2330e2d9809884de776", + "baseChecksum": "04627d882217f6ca0b5db70ab11645bd", + "status": "translated" + }, + "ja": { + "checksum": "35cd45233f06236bdf391a00c1fded6b", + "baseChecksum": "04627d882217f6ca0b5db70ab11645bd", + "status": "translated" + }, + "de": { + "checksum": "e43350b1f44582905f1cd89d1f94f9d6", + "baseChecksum": "04627d882217f6ca0b5db70ab11645bd", + "status": "translated" } }, "commentHint": { @@ -177,6 +342,21 @@ "checksum": "ce2f8d8be24963472f82d4b2b9d50ade", "baseChecksum": "7eec8425c820eebb9e066bede699ee5a", "status": "translated" + }, + "ru": { + "checksum": "1b226402bd8bdd4118f24dc87d0a6ea4", + "baseChecksum": "7eec8425c820eebb9e066bede699ee5a", + "status": "translated" + }, + "ja": { + "checksum": "2e8eeeb380e984cdcccd9de325bdf498", + "baseChecksum": "7eec8425c820eebb9e066bede699ee5a", + "status": "translated" + }, + "de": { + "checksum": "81dbe7fc7ae07ced1d92d2f485fb480b", + "baseChecksum": "7eec8425c820eebb9e066bede699ee5a", + "status": "translated" } }, "otherLocalesToggleX": { @@ -192,6 +372,21 @@ "checksum": "bc079033bb772e8a21525f9064bd47b7", "baseChecksum": "bf32152e1d3fd4d222bf92e179a25a7e", "status": "stale" + }, + "ru": { + "checksum": "0bd39f06176ffb76f44bfb101e822487", + "baseChecksum": "bf32152e1d3fd4d222bf92e179a25a7e", + "status": "translated" + }, + "ja": { + "checksum": "d67637567b1cf7744bbb08f2bb17901f", + "baseChecksum": "bf32152e1d3fd4d222bf92e179a25a7e", + "status": "translated" + }, + "de": { + "checksum": "32ea44efe3ca412e0ed666b3007a3057", + "baseChecksum": "bf32152e1d3fd4d222bf92e179a25a7e", + "status": "translated" } }, "status": { @@ -207,6 +402,21 @@ "checksum": "87a831bc99060c55b50dbe91c6aab6e9", "baseChecksum": "ec53a8c4f07baed5d8825072c89799be", "status": "translated" + }, + "ru": { + "checksum": "7203f7a4ff564cb876e8db54c903dbfc", + "baseChecksum": "ec53a8c4f07baed5d8825072c89799be", + "status": "translated" + }, + "ja": { + "checksum": "c70d256fb435a533d8ec2bbbcded1614", + "baseChecksum": "ec53a8c4f07baed5d8825072c89799be", + "status": "translated" + }, + "de": { + "checksum": "ec53a8c4f07baed5d8825072c89799be", + "baseChecksum": "ec53a8c4f07baed5d8825072c89799be", + "status": "translated" } }, "saving": { @@ -222,6 +432,21 @@ "checksum": "c6b16cb467ec9ee9a2f3e4c7f6f7ac30", "baseChecksum": "575f5f86d2c7ea113c6710c1037c4465", "status": "translated" + }, + "ru": { + "checksum": "c15f152fce72c2e173576d2915651fd4", + "baseChecksum": "575f5f86d2c7ea113c6710c1037c4465", + "status": "translated" + }, + "ja": { + "checksum": "2a33020e5b56902e4a5609063f5428d7", + "baseChecksum": "575f5f86d2c7ea113c6710c1037c4465", + "status": "translated" + }, + "de": { + "checksum": "87ed3dee318d7e79bec2e34d05d54a3c", + "baseChecksum": "575f5f86d2c7ea113c6710c1037c4465", + "status": "translated" } }, "editTitle": { @@ -237,6 +462,21 @@ "checksum": "faddb24e4a6d65187240a73f67279d41", "baseChecksum": "305253475cc868103805068f45a90468", "status": "translated" + }, + "ru": { + "checksum": "420f0d3ce399f2011c6ed08db0966aeb", + "baseChecksum": "305253475cc868103805068f45a90468", + "status": "translated" + }, + "ja": { + "checksum": "68977133e365bb4aabaa769438bbd99b", + "baseChecksum": "305253475cc868103805068f45a90468", + "status": "translated" + }, + "de": { + "checksum": "fe65d49ee802525c78ef798bbf7fa7ff", + "baseChecksum": "305253475cc868103805068f45a90468", + "status": "translated" } }, "createTitle": { @@ -252,6 +492,21 @@ "checksum": "6dace602a9413456da723a74ccea1247", "baseChecksum": "dabf3cb410b22a2cd138d2ebe54717b1", "status": "translated" + }, + "ru": { + "checksum": "44dadb05d363f38d2b90a564e5aa5cde", + "baseChecksum": "dabf3cb410b22a2cd138d2ebe54717b1", + "status": "translated" + }, + "ja": { + "checksum": "171e5294db84907dcb90354c51dda198", + "baseChecksum": "dabf3cb410b22a2cd138d2ebe54717b1", + "status": "translated" + }, + "de": { + "checksum": "52279682a6da0375eca2ee0189703aa1", + "baseChecksum": "dabf3cb410b22a2cd138d2ebe54717b1", + "status": "translated" } }, "editSubtitle": { @@ -267,6 +522,21 @@ "checksum": "1a04f0f7a053bfba0aee45213a2d446f", "baseChecksum": "d28295dc73579f448ff1c671d3bb8a21", "status": "translated" + }, + "ru": { + "checksum": "87072ea6ecc477a8a303d165f40707fa", + "baseChecksum": "d28295dc73579f448ff1c671d3bb8a21", + "status": "translated" + }, + "ja": { + "checksum": "524e3e2cae828d746543516784ca8e59", + "baseChecksum": "d28295dc73579f448ff1c671d3bb8a21", + "status": "translated" + }, + "de": { + "checksum": "17663fb242b32e9ae73255c778cc9513", + "baseChecksum": "d28295dc73579f448ff1c671d3bb8a21", + "status": "translated" } }, "createSubtitle": { @@ -282,6 +552,21 @@ "checksum": "31a8eb02e385879908aa6189c52e9cd7", "baseChecksum": "78d0cb0cae838471875c9ddca9da020c", "status": "translated" + }, + "ru": { + "checksum": "b63e40a456682ec423e0093a38ca5325", + "baseChecksum": "78d0cb0cae838471875c9ddca9da020c", + "status": "translated" + }, + "ja": { + "checksum": "9cff0b30b42d5a2e7c813a494c3cafd1", + "baseChecksum": "78d0cb0cae838471875c9ddca9da020c", + "status": "translated" + }, + "de": { + "checksum": "39b82c77eb9f900eb19a9fec1f1a38d8", + "baseChecksum": "78d0cb0cae838471875c9ddca9da020c", + "status": "translated" } }, "updateButton": { @@ -297,6 +582,21 @@ "checksum": "932e59c4532010533cca59bdfc93fc9f", "baseChecksum": "e8d2af23aa47989c080ffc7252646485", "status": "translated" + }, + "ru": { + "checksum": "e3301cba3a8328585a5d8da49efabae7", + "baseChecksum": "e8d2af23aa47989c080ffc7252646485", + "status": "translated" + }, + "ja": { + "checksum": "1540d03eec10bf998ff2bb5e35a24073", + "baseChecksum": "e8d2af23aa47989c080ffc7252646485", + "status": "translated" + }, + "de": { + "checksum": "18c445c51e69f22062658cebff3c2818", + "baseChecksum": "e8d2af23aa47989c080ffc7252646485", + "status": "translated" } }, "saveButton": { @@ -312,6 +612,21 @@ "checksum": "0a65eff2cde1b1c920bc8bfca7fb0a6f", "baseChecksum": "d503198287eeadd483ae40abef48027a", "status": "translated" + }, + "ru": { + "checksum": "56c170b801d292304f7d51848bbbb5b1", + "baseChecksum": "d503198287eeadd483ae40abef48027a", + "status": "translated" + }, + "ja": { + "checksum": "b0b41dcc457c3d6888856ad2784a5114", + "baseChecksum": "d503198287eeadd483ae40abef48027a", + "status": "translated" + }, + "de": { + "checksum": "ccaa8b7bda6ec28440fd197f582fdb63", + "baseChecksum": "d503198287eeadd483ae40abef48027a", + "status": "translated" } }, "keyCopied": { @@ -327,6 +642,21 @@ "checksum": "85f05ad1c3d4d31a2d7e9528908c6b9e", "baseChecksum": "c605635c89ace9747c30b35a6ce64ae5", "status": "translated" + }, + "ru": { + "checksum": "daff2f6a15fc189a32b84e96842f40b8", + "baseChecksum": "c605635c89ace9747c30b35a6ce64ae5", + "status": "translated" + }, + "ja": { + "checksum": "c7bda30afa60f8e97716d6dd6733d296", + "baseChecksum": "c605635c89ace9747c30b35a6ce64ae5", + "status": "translated" + }, + "de": { + "checksum": "1a9062fe9c6575a321265086c4cccc21", + "baseChecksum": "c605635c89ace9747c30b35a6ce64ae5", + "status": "translated" } }, "copyFailed": { @@ -342,6 +672,21 @@ "checksum": "7ceeff034e95092dd8798b12ba572014", "baseChecksum": "e608b2fe7089e4fa80b73b4f9c03fb61", "status": "translated" + }, + "ru": { + "checksum": "c63eb8553a973244e9929fb545ba6a68", + "baseChecksum": "e608b2fe7089e4fa80b73b4f9c03fb61", + "status": "translated" + }, + "ja": { + "checksum": "a3be8780485e9d6cb6ac1b61fe24e2cb", + "baseChecksum": "e608b2fe7089e4fa80b73b4f9c03fb61", + "status": "translated" + }, + "de": { + "checksum": "eee387fa8f8f8ee4d3446cfe9fcfe545", + "baseChecksum": "e608b2fe7089e4fa80b73b4f9c03fb61", + "status": "translated" } }, "keyRequired": { @@ -357,6 +702,21 @@ "checksum": "ea28c6adb63a2757e793c1cd43c4ec9b", "baseChecksum": "a2f067165e800ad99feffdad954be4de", "status": "translated" + }, + "ru": { + "checksum": "2d03396b3c9738a779c930607eec3737", + "baseChecksum": "a2f067165e800ad99feffdad954be4de", + "status": "translated" + }, + "ja": { + "checksum": "77718f9d7783ee2e6cb1879121aed163", + "baseChecksum": "a2f067165e800ad99feffdad954be4de", + "status": "translated" + }, + "de": { + "checksum": "fcd753f4a25ac68319b2ed31a5381afc", + "baseChecksum": "a2f067165e800ad99feffdad954be4de", + "status": "translated" } }, "keyPatternError": { @@ -372,6 +732,21 @@ "checksum": "7552d3fca2f3b4d304ddf128cd1619f6", "baseChecksum": "a5fe09c595ead0cd466e781fc4e87dbe", "status": "translated" + }, + "ru": { + "checksum": "9f5fa4fee28b782fab639f3433c9d2eb", + "baseChecksum": "a5fe09c595ead0cd466e781fc4e87dbe", + "status": "translated" + }, + "ja": { + "checksum": "1e1b5c2f4f5aed3d88fab601e91f55f7", + "baseChecksum": "a5fe09c595ead0cd466e781fc4e87dbe", + "status": "translated" + }, + "de": { + "checksum": "bcdd26c99eee838f7b84e91bdcf7d1ac", + "baseChecksum": "a5fe09c595ead0cd466e781fc4e87dbe", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/translationItem/resource_entries.json b/apps/tracker/src/i18n/browser/translationItem/resource_entries.json index 2d41e4e7..b166651f 100644 --- a/apps/tracker/src/i18n/browser/translationItem/resource_entries.json +++ b/apps/tracker/src/i18n/browser/translationItem/resource_entries.json @@ -4,62 +4,89 @@ "comment": "Aria-label for the drag handle on a translation item", "tags": ["browser"], "es": "Arrastrar para mover la traducción", - "fr-ca": "Faites glisser pour déplacer la traduction" + "fr-ca": "Faites glisser pour déplacer la traduction", + "ru": "Перетащите, чтобы переместить перевод.", + "ja": "ドラッグして翻訳を移動", + "de": "Zum Verschieben der Übersetzung ziehen" }, "copyKeyAriaLabel": { "source": "Copy key", "comment": "Aria-label for the copy key button on a translation item header", "tags": ["browser"], "es": "Copiar clave", - "fr-ca": "Copier la clé" + "fr-ca": "Copier la clé", + "ru": "Копировать ключ", + "ja": "コピーキー", + "de": "Schlüssel kopieren" }, "hideCommentAriaLabel": { "source": "Hide comment", "comment": "Aria-label for the comment toggle button when comment is currently shown", "tags": ["browser"], "es": "Ocultar comentario", - "fr-ca": "Masquer le commentaire" + "fr-ca": "Masquer le commentaire", + "ru": "Скрыть комментарий", + "ja": "コメントを非表示にする", + "de": "Kommentar ausblenden" }, "showCommentAriaLabel": { "source": "Show comment", "comment": "Aria-label for the comment toggle button when comment is currently hidden", "tags": ["browser"], "es": "Mostrar comentario", - "fr-ca": "Afficher le commentaire" + "fr-ca": "Afficher le commentaire", + "ru": "Показать комментарий", + "ja": "コメントを表示", + "de": "Kommentar anzeigen" }, "moreActionsAriaLabel": { "source": "More actions", "comment": "Aria-label for the more actions menu trigger button on a translation item", "tags": ["browser"], "es": "Más acciones", - "fr-ca": "Plus d'actions" + "fr-ca": "Plus d'actions", + "ru": "Дополнительные действия", + "ja": "その他の操作", + "de": "Weitere Aktionen" }, "editAriaLabel": { "source": "Edit translation", "comment": "Aria-label for the Edit menu item in the translation item actions menu", "tags": ["browser"], "es": "Editar traducción", - "fr-ca": "Modifier la traduction" + "fr-ca": "Modifier la traduction", + "ru": "Редактировать перевод", + "ja": "翻訳を編集する", + "de": "Übersetzung bearbeiten" }, "translateAriaLabel": { "source": "Translate resource", "comment": "Aria-label for the Translate menu item in the translation item actions menu", "tags": ["browser"], "es": "Traducir recurso", - "fr-ca": "ressource de traduction" + "fr-ca": "ressource de traduction", + "ru": "Перевести ресурс", + "ja": "リソースを翻訳する", + "de": "Ressource übersetzen" }, "deleteAriaLabel": { "source": "Delete translation", "comment": "Aria-label for the Delete menu item in the translation item actions menu", "tags": ["browser"], "es": "Eliminar traducción", - "fr-ca": "Supprimer la traduction" + "fr-ca": "Supprimer la traduction", + "ru": "Удалить перевод", + "ja": "翻訳を削除", + "de": "Übersetzung löschen" }, "noStatuses": { "source": "No statuses", "comment": "Screen-reader text shown in status breakdown when no translation statuses are available", "tags": ["browser"], "es": "Sin estados", - "fr-ca": "Aucun statut" + "fr-ca": "Aucun statut", + "ru": "Нет статусов", + "ja": "ステータスなし", + "de": "Keine Statusmeldungen" } } diff --git a/apps/tracker/src/i18n/browser/translationItem/tracker_meta.json b/apps/tracker/src/i18n/browser/translationItem/tracker_meta.json index 94244e79..471dbb68 100644 --- a/apps/tracker/src/i18n/browser/translationItem/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/translationItem/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "09dbbc85f5e11013eb9067bf66405f44", "baseChecksum": "68124efca03350fd7d6da755400d15c0", "status": "translated" + }, + "ru": { + "checksum": "2128d13dfe14d26e4f3fcf78b43f2953", + "baseChecksum": "68124efca03350fd7d6da755400d15c0", + "status": "translated" + }, + "ja": { + "checksum": "b651e01207671b538231c80fa0d49546", + "baseChecksum": "68124efca03350fd7d6da755400d15c0", + "status": "translated" + }, + "de": { + "checksum": "5cfb44a9e950d50700c949248f97dbc3", + "baseChecksum": "68124efca03350fd7d6da755400d15c0", + "status": "translated" } }, "copyKeyAriaLabel": { @@ -27,6 +42,21 @@ "checksum": "b2581a92e7db3a59b61db2e29cd5379b", "baseChecksum": "819c7746f5e0a2af0fd512b5ea7ece90", "status": "translated" + }, + "ru": { + "checksum": "0825c26b70c6f32db71b9705d16f7382", + "baseChecksum": "819c7746f5e0a2af0fd512b5ea7ece90", + "status": "translated" + }, + "ja": { + "checksum": "40388375ca056587f52bebf7aa1c6f01", + "baseChecksum": "819c7746f5e0a2af0fd512b5ea7ece90", + "status": "translated" + }, + "de": { + "checksum": "75456b1abc45aa5521e88abf70c79831", + "baseChecksum": "819c7746f5e0a2af0fd512b5ea7ece90", + "status": "translated" } }, "hideCommentAriaLabel": { @@ -42,6 +72,21 @@ "checksum": "db457af4e0e015ded09a75087331b01b", "baseChecksum": "2204356776748f7de4c06b8d0e77ff37", "status": "translated" + }, + "ru": { + "checksum": "d2578e5524e6d239d2fd4c13454080ab", + "baseChecksum": "2204356776748f7de4c06b8d0e77ff37", + "status": "translated" + }, + "ja": { + "checksum": "28da42e28fcfb4002d34b713612753d4", + "baseChecksum": "2204356776748f7de4c06b8d0e77ff37", + "status": "translated" + }, + "de": { + "checksum": "8e76d8bec928869a96ce8bf9aa3154c4", + "baseChecksum": "2204356776748f7de4c06b8d0e77ff37", + "status": "translated" } }, "showCommentAriaLabel": { @@ -57,6 +102,21 @@ "checksum": "b586ba13de37dc60e1ba12d73a553586", "baseChecksum": "ba109df70b5131f0f40f1726498c620e", "status": "translated" + }, + "ru": { + "checksum": "318ab77d48ee4f17a9e63b35b7d22132", + "baseChecksum": "ba109df70b5131f0f40f1726498c620e", + "status": "translated" + }, + "ja": { + "checksum": "7e7a3bd986703ee6b48bfc76a415f9da", + "baseChecksum": "ba109df70b5131f0f40f1726498c620e", + "status": "translated" + }, + "de": { + "checksum": "9e2e52ba03ba3c051cfd9962baa285bf", + "baseChecksum": "ba109df70b5131f0f40f1726498c620e", + "status": "translated" } }, "moreActionsAriaLabel": { @@ -72,6 +132,21 @@ "checksum": "42d9477a48c9538ad547198f86bfb226", "baseChecksum": "284716247b12b363fd6b6a71bff0918e", "status": "translated" + }, + "ru": { + "checksum": "480a85fa79cb183ea54cfd5c53e52888", + "baseChecksum": "284716247b12b363fd6b6a71bff0918e", + "status": "translated" + }, + "ja": { + "checksum": "e334d8acd386b855251c8e086546d3d4", + "baseChecksum": "284716247b12b363fd6b6a71bff0918e", + "status": "translated" + }, + "de": { + "checksum": "b7405e747816fecc21fc8185a08dd620", + "baseChecksum": "284716247b12b363fd6b6a71bff0918e", + "status": "translated" } }, "editAriaLabel": { @@ -87,6 +162,21 @@ "checksum": "faddb24e4a6d65187240a73f67279d41", "baseChecksum": "a7f6326fc128712ffaee83351ea67525", "status": "translated" + }, + "ru": { + "checksum": "420f0d3ce399f2011c6ed08db0966aeb", + "baseChecksum": "a7f6326fc128712ffaee83351ea67525", + "status": "translated" + }, + "ja": { + "checksum": "68977133e365bb4aabaa769438bbd99b", + "baseChecksum": "a7f6326fc128712ffaee83351ea67525", + "status": "translated" + }, + "de": { + "checksum": "fe65d49ee802525c78ef798bbf7fa7ff", + "baseChecksum": "a7f6326fc128712ffaee83351ea67525", + "status": "translated" } }, "translateAriaLabel": { @@ -102,6 +192,21 @@ "checksum": "c0241b4e360b27cca2b09dd7bfb4779d", "baseChecksum": "ff613241f6b08efa55b06e01aa32dcce", "status": "translated" + }, + "ru": { + "checksum": "3f22abe764ae7932bee7be351c1daa11", + "baseChecksum": "ff613241f6b08efa55b06e01aa32dcce", + "status": "translated" + }, + "ja": { + "checksum": "87d4481c4eab0e8f22b481081f8f5828", + "baseChecksum": "ff613241f6b08efa55b06e01aa32dcce", + "status": "translated" + }, + "de": { + "checksum": "e573db5182f49b8bf396f2918f055fd9", + "baseChecksum": "ff613241f6b08efa55b06e01aa32dcce", + "status": "translated" } }, "deleteAriaLabel": { @@ -117,6 +222,21 @@ "checksum": "78033b482df4030cef566343dbb0f639", "baseChecksum": "cbad46a31c2032cd81b3c74e7ee6ce7a", "status": "translated" + }, + "ru": { + "checksum": "9cdcd35d38e395a10dc8fd5021239714", + "baseChecksum": "cbad46a31c2032cd81b3c74e7ee6ce7a", + "status": "translated" + }, + "ja": { + "checksum": "ab1412c6f45b4215c15f900b24c7948e", + "baseChecksum": "cbad46a31c2032cd81b3c74e7ee6ce7a", + "status": "translated" + }, + "de": { + "checksum": "c6c30c0bcfe692031941e62d907577bd", + "baseChecksum": "cbad46a31c2032cd81b3c74e7ee6ce7a", + "status": "translated" } }, "noStatuses": { @@ -132,6 +252,21 @@ "checksum": "5473390fc7c6e2799032cec4df13b34c", "baseChecksum": "7c7917a58dcd74962c36abf81de3903f", "status": "translated" + }, + "ru": { + "checksum": "d949136208fa1d59d72e8fa04becd3bb", + "baseChecksum": "7c7917a58dcd74962c36abf81de3903f", + "status": "translated" + }, + "ja": { + "checksum": "ba459d648257e215392475f073532d54", + "baseChecksum": "7c7917a58dcd74962c36abf81de3903f", + "status": "translated" + }, + "de": { + "checksum": "9047977d73edfd8db3e0a2ad96cdafb9", + "baseChecksum": "7c7917a58dcd74962c36abf81de3903f", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/translationList/resource_entries.json b/apps/tracker/src/i18n/browser/translationList/resource_entries.json index fc09c849..ccab4b92 100644 --- a/apps/tracker/src/i18n/browser/translationList/resource_entries.json +++ b/apps/tracker/src/i18n/browser/translationList/resource_entries.json @@ -4,6 +4,9 @@ "comment": "Aria-label for the virtual scroll viewport containing the list of translations", "tags": ["browser"], "es": "Lista de traducciones", - "fr-ca": "Liste de traductions" + "fr-ca": "Liste de traductions", + "ru": "Список переводов", + "ja": "翻訳リスト", + "de": "Übersetzungsliste" } } diff --git a/apps/tracker/src/i18n/browser/translationList/tracker_meta.json b/apps/tracker/src/i18n/browser/translationList/tracker_meta.json index e17bad1a..dbacb201 100644 --- a/apps/tracker/src/i18n/browser/translationList/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/translationList/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "ccdfbdc83b7ed690c123b9cb9787dfc2", "baseChecksum": "d96ae1865ec25b9e1707839a47d5d52e", "status": "translated" + }, + "ru": { + "checksum": "38cbe2fba73233baff4d365eefb00a4a", + "baseChecksum": "d96ae1865ec25b9e1707839a47d5d52e", + "status": "translated" + }, + "ja": { + "checksum": "a7229f7cacfc120fcd463a552a0367bb", + "baseChecksum": "d96ae1865ec25b9e1707839a47d5d52e", + "status": "translated" + }, + "de": { + "checksum": "f2b91ddee1d777a277c342782cf52e32", + "baseChecksum": "d96ae1865ec25b9e1707839a47d5d52e", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/browser/translationSearch/resource_entries.json b/apps/tracker/src/i18n/browser/translationSearch/resource_entries.json index 13c63cdf..c9c175a3 100644 --- a/apps/tracker/src/i18n/browser/translationSearch/resource_entries.json +++ b/apps/tracker/src/i18n/browser/translationSearch/resource_entries.json @@ -4,6 +4,9 @@ "comment": "Aria-label for the translation search input in the main translation header", "tags": ["browser"], "es": "Buscar traducciones", - "fr-ca": "Recherche de traductions" + "fr-ca": "Recherche de traductions", + "ru": "Поиск переводов", + "ja": "翻訳を検索", + "de": "Übersetzungen suchen" } } diff --git a/apps/tracker/src/i18n/browser/translationSearch/tracker_meta.json b/apps/tracker/src/i18n/browser/translationSearch/tracker_meta.json index 13f1ff5a..a00611f0 100644 --- a/apps/tracker/src/i18n/browser/translationSearch/tracker_meta.json +++ b/apps/tracker/src/i18n/browser/translationSearch/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "f20cd2443adc8f77c8e0e12c8fcaf7a7", "baseChecksum": "e3ee9f9a340e253eb5196ce7d53ae2d8", "status": "translated" + }, + "ru": { + "checksum": "3970fa93ce20322f721cdc90ddc0ec39", + "baseChecksum": "e3ee9f9a340e253eb5196ce7d53ae2d8", + "status": "translated" + }, + "ja": { + "checksum": "80573c73a72040dad26c737a0c300ddf", + "baseChecksum": "e3ee9f9a340e253eb5196ce7d53ae2d8", + "status": "translated" + }, + "de": { + "checksum": "e37d068a8dda17731244094cd605371c", + "baseChecksum": "e3ee9f9a340e253eb5196ce7d53ae2d8", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/collections/card/resource_entries.json b/apps/tracker/src/i18n/collections/card/resource_entries.json index 0c94e253..7fb82db2 100644 --- a/apps/tracker/src/i18n/collections/card/resource_entries.json +++ b/apps/tracker/src/i18n/collections/card/resource_entries.json @@ -4,20 +4,29 @@ "comment": "Accessible label for edit icon button on collection card", "tags": ["card", "collection"], "es": "Editar colección", - "fr-ca": "Modifier la collection" + "fr-ca": "Modifier la collection", + "ru": "Редактировать коллекцию", + "ja": "コレクションを編集", + "de": "Sammlung bearbeiten" }, "delete": { "source": "Delete collection", "comment": "Accessible label for delete icon button on collection card", "tags": ["card", "collection"], "es": "Eliminar colección", - "fr-ca": "Supprimer la collection" + "fr-ca": "Supprimer la collection", + "ru": "Удалить коллекцию", + "ja": "コレクションを削除", + "de": "Sammlung löschen" }, "moreActionsAriaLabel": { "source": "More actions for collection", "comment": "Aria label for the more actions button on a collection card", "tags": ["collections"], "es": "Más acciones para la recolección", - "fr-ca": "Plus d'actions pour la collecte" + "fr-ca": "Plus d'actions pour la collecte", + "ru": "Дополнительные действия для сбора", + "ja": "収集のためのその他のアクション", + "de": "Weitere Aktionen zur Sammlung" } } diff --git a/apps/tracker/src/i18n/collections/card/tracker_meta.json b/apps/tracker/src/i18n/collections/card/tracker_meta.json index ff6abe3e..71b9e0d6 100644 --- a/apps/tracker/src/i18n/collections/card/tracker_meta.json +++ b/apps/tracker/src/i18n/collections/card/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "29ab3c9f022d5d28e6d5ea87be010057", "baseChecksum": "2687006ffa30f69f72187cbb690d6cc0", "status": "new" + }, + "ru": { + "checksum": "fc542666f0b02b7b83ef1c93f694726c", + "baseChecksum": "2687006ffa30f69f72187cbb690d6cc0", + "status": "translated" + }, + "ja": { + "checksum": "62c71b3f7f45a8b6da35ef6a135cc061", + "baseChecksum": "2687006ffa30f69f72187cbb690d6cc0", + "status": "translated" + }, + "de": { + "checksum": "f7537fa7c0c52321d16635b4085d8cd1", + "baseChecksum": "2687006ffa30f69f72187cbb690d6cc0", + "status": "translated" } }, "delete": { @@ -27,6 +42,21 @@ "checksum": "66a9a5432f50dc163fec6cb64d2c88b3", "baseChecksum": "611307b7abf62c8f6ffc374701393f29", "status": "new" + }, + "ru": { + "checksum": "0f440420a40b59ebe5a8eae593b4bc31", + "baseChecksum": "611307b7abf62c8f6ffc374701393f29", + "status": "translated" + }, + "ja": { + "checksum": "f87f76e7fdb4ade8d4a1a42261f66690", + "baseChecksum": "611307b7abf62c8f6ffc374701393f29", + "status": "translated" + }, + "de": { + "checksum": "6710cad93dd626ec137f04cac9ce366d", + "baseChecksum": "611307b7abf62c8f6ffc374701393f29", + "status": "translated" } }, "moreActionsAriaLabel": { @@ -42,6 +72,21 @@ "checksum": "7178ecf6f4ecbdfbfae955ae5d30452c", "baseChecksum": "4f46bf6697514d7744218c4a5184b8b0", "status": "translated" + }, + "ru": { + "checksum": "9909138ddecc5b4abe148b463dc91387", + "baseChecksum": "4f46bf6697514d7744218c4a5184b8b0", + "status": "translated" + }, + "ja": { + "checksum": "e0313b185e9d3b4110e78b7f93aa09d6", + "baseChecksum": "4f46bf6697514d7744218c4a5184b8b0", + "status": "translated" + }, + "de": { + "checksum": "487d1698f0bbde9960fc27c46676cb50", + "baseChecksum": "4f46bf6697514d7744218c4a5184b8b0", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/collections/dialog/create/resource_entries.json b/apps/tracker/src/i18n/collections/dialog/create/resource_entries.json index c7fc4159..90f8ed35 100644 --- a/apps/tracker/src/i18n/collections/dialog/create/resource_entries.json +++ b/apps/tracker/src/i18n/collections/dialog/create/resource_entries.json @@ -3,6 +3,9 @@ "source": "Create Collection", "comment": "Dialog title when creating a new collection", "es": "Crear Colección", - "fr-ca": "Créer une Collection" + "fr-ca": "Créer une Collection", + "ru": "Создать коллекцию", + "ja": "コレクションを作成する", + "de": "Sammlung erstellen" } } diff --git a/apps/tracker/src/i18n/collections/dialog/create/tracker_meta.json b/apps/tracker/src/i18n/collections/dialog/create/tracker_meta.json index 61c79ed2..4b6091bd 100644 --- a/apps/tracker/src/i18n/collections/dialog/create/tracker_meta.json +++ b/apps/tracker/src/i18n/collections/dialog/create/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "ede7465a10ac320690ce98a92a9515ce", "baseChecksum": "57c313ed48acfddf01bcbf4b3e4de556", "status": "new" + }, + "ru": { + "checksum": "f2758a5f11d0f14b901f83f75ca4b178", + "baseChecksum": "57c313ed48acfddf01bcbf4b3e4de556", + "status": "translated" + }, + "ja": { + "checksum": "5cc609a13047f3b1cb6388fd6e9583c1", + "baseChecksum": "57c313ed48acfddf01bcbf4b3e4de556", + "status": "translated" + }, + "de": { + "checksum": "8215c35839bdf9c5fe8379112e398fa7", + "baseChecksum": "57c313ed48acfddf01bcbf4b3e4de556", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/collections/dialog/delete/resource_entries.json b/apps/tracker/src/i18n/collections/dialog/delete/resource_entries.json index 2462f95a..98e70213 100644 --- a/apps/tracker/src/i18n/collections/dialog/delete/resource_entries.json +++ b/apps/tracker/src/i18n/collections/dialog/delete/resource_entries.json @@ -3,12 +3,18 @@ "source": "Delete Collection", "comment": "Confirmation dialog title when deleting a collection", "es": "Eliminar Colección", - "fr-ca": "Supprimer la Collection" + "fr-ca": "Supprimer la Collection", + "ru": "Удалить коллекцию", + "ja": "コレクションを削除", + "de": "Sammlung löschen" }, "message": { "source": "Are you sure you want to delete {name}?", "comment": "Confirmation message with collection name placeholder", "es": "¿Estás seguro de que deseas eliminar {name}?", - "fr-ca": "Êtes-vous sûr de vouloir supprimer {name}?" + "fr-ca": "Êtes-vous sûr de vouloir supprimer {name}?", + "ru": "Вы уверены, что хотите удалить {name}?", + "ja": "{name} を削除してもよろしいですか?", + "de": "Sind Sie sicher, dass Sie {name} löschen möchten?" } } diff --git a/apps/tracker/src/i18n/collections/dialog/delete/tracker_meta.json b/apps/tracker/src/i18n/collections/dialog/delete/tracker_meta.json index 0ed6aadd..19f1e965 100644 --- a/apps/tracker/src/i18n/collections/dialog/delete/tracker_meta.json +++ b/apps/tracker/src/i18n/collections/dialog/delete/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "48beba344a9bf3fe590da79bd990c1ad", "baseChecksum": "8cea924216e9aff75416cfe2a64e362e", "status": "new" + }, + "ru": { + "checksum": "0f440420a40b59ebe5a8eae593b4bc31", + "baseChecksum": "8cea924216e9aff75416cfe2a64e362e", + "status": "translated" + }, + "ja": { + "checksum": "f87f76e7fdb4ade8d4a1a42261f66690", + "baseChecksum": "8cea924216e9aff75416cfe2a64e362e", + "status": "translated" + }, + "de": { + "checksum": "6710cad93dd626ec137f04cac9ce366d", + "baseChecksum": "8cea924216e9aff75416cfe2a64e362e", + "status": "translated" } }, "message": { @@ -27,6 +42,21 @@ "checksum": "07447e6ba3a9f5a7b53190d3ceded3ad", "baseChecksum": "df278e737e65dbbac79ec7c2ae2ea04e", "status": "stale" + }, + "ru": { + "checksum": "8e9636f32d40af6bd958012fed558f26", + "baseChecksum": "df278e737e65dbbac79ec7c2ae2ea04e", + "status": "translated" + }, + "ja": { + "checksum": "cf8190775fd35a0a75bb78b90a8a0847", + "baseChecksum": "df278e737e65dbbac79ec7c2ae2ea04e", + "status": "translated" + }, + "de": { + "checksum": "0d6f811505d1cfccc0faa35cca4b7e2c", + "baseChecksum": "df278e737e65dbbac79ec7c2ae2ea04e", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/collections/dialog/edit/resource_entries.json b/apps/tracker/src/i18n/collections/dialog/edit/resource_entries.json index 16cf4a2a..3aa8affb 100644 --- a/apps/tracker/src/i18n/collections/dialog/edit/resource_entries.json +++ b/apps/tracker/src/i18n/collections/dialog/edit/resource_entries.json @@ -3,6 +3,9 @@ "source": "Edit Collection", "comment": "Dialog title when editing an existing collection", "es": "Editar Colección", - "fr-ca": "Modifier la Collection" + "fr-ca": "Modifier la Collection", + "ru": "Редактировать коллекцию", + "ja": "コレクションを編集", + "de": "Sammlung bearbeiten" } } diff --git a/apps/tracker/src/i18n/collections/dialog/edit/tracker_meta.json b/apps/tracker/src/i18n/collections/dialog/edit/tracker_meta.json index fa2a9114..c91e8d88 100644 --- a/apps/tracker/src/i18n/collections/dialog/edit/tracker_meta.json +++ b/apps/tracker/src/i18n/collections/dialog/edit/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "4eccf5449475d38715d4d54aa6fdad49", "baseChecksum": "bcc40d0f321165f8d57c4185fc0357df", "status": "new" + }, + "ru": { + "checksum": "fc542666f0b02b7b83ef1c93f694726c", + "baseChecksum": "bcc40d0f321165f8d57c4185fc0357df", + "status": "translated" + }, + "ja": { + "checksum": "62c71b3f7f45a8b6da35ef6a135cc061", + "baseChecksum": "bcc40d0f321165f8d57c4185fc0357df", + "status": "translated" + }, + "de": { + "checksum": "f7537fa7c0c52321d16635b4085d8cd1", + "baseChecksum": "bcc40d0f321165f8d57c4185fc0357df", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/collections/dialog/resource_entries.json b/apps/tracker/src/i18n/collections/dialog/resource_entries.json index cd4df0ce..3252092e 100644 --- a/apps/tracker/src/i18n/collections/dialog/resource_entries.json +++ b/apps/tracker/src/i18n/collections/dialog/resource_entries.json @@ -3,65 +3,98 @@ "source": "Collection Name", "comment": "Label for collection name input field", "es": "Nombre de la Colección", - "fr-ca": "Nom de la Collection" + "fr-ca": "Nom de la Collection", + "ru": "Название коллекции", + "ja": "コレクション名", + "de": "Sammlungsname" }, "namePlaceholder": { "source": "e.g., my-app-i18n", "comment": "Placeholder text for collection name input", "es": "ej., mi-app-i18n", - "fr-ca": "p. ex., mon-app-i18n" + "fr-ca": "p. ex., mon-app-i18n", + "ru": "например, my-app-i18n", + "ja": "例:my-app-i18n", + "de": "z.B. meine-app-i18n" }, "nameRequired": { "source": "Collection name is required", "comment": "Error message when name is required", "es": "El nombre de la colección es obligatorio", - "fr-ca": "Le nom de la collection est requis" + "fr-ca": "Le nom de la collection est requis", + "ru": "Название коллекции обязательно для указания.", + "ja": "コレクション名は必須です。", + "de": "Ein Sammlungsname ist erforderlich." }, "folderLabel": { "source": "Translations Folder", "comment": "Label for translations folder input field", "es": "Carpeta de Traducciones", - "fr-ca": "Dossier de Traductions" + "fr-ca": "Dossier de Traductions", + "ru": "Папка переводов", + "ja": "翻訳フォルダ", + "de": "Übersetzungsordner" }, "folderPlaceholder": { "source": "e.g., ./src/assets/i18n", "comment": "Placeholder text for folder path input", "es": "ej., ./src/assets/i18n", - "fr-ca": "p. ex., ./src/assets/i18n" + "fr-ca": "p. ex., ./src/assets/i18n", + "ru": "например, ./src/assets/i18n", + "ja": "例:./src/assets/i18n", + "de": "z. B. ./src/assets/i18n" }, "folderRequired": { "source": "Translations folder is required", "comment": "Error message when folder is required", "es": "La carpeta de traducciones es obligatoria", - "fr-ca": "Le dossier de traductions est requis" + "fr-ca": "Le dossier de traductions est requis", + "ru": "Необходима папка «Переводы».", + "ja": "翻訳フォルダが必要です", + "de": "Der Ordner „Übersetzungen“ wird benötigt." }, "localesLabel": { "source": "Locales (Optional)", "comment": "Label for locales input field", "es": "Idiomas (Opcional)", - "fr-ca": "Langues (Optionnel)" + "fr-ca": "Langues (Optionnel)", + "ru": "Локали (необязательно)", + "ja": "ロケール(オプション)", + "de": "Regionen (optional)" }, "localesHint": { "source": "Comma-separated list of locale codes. Leave empty to use global config.", "comment": "Hint text for locales input", "es": "Lista de códigos de idioma separados por comas. Dejar vacío para usar la configuración global.", - "fr-ca": "Liste de codes de langue séparés par des virgules. Laisser vide pour utiliser la configuration globale." + "fr-ca": "Liste de codes de langue séparés par des virgules. Laisser vide pour utiliser la configuration globale.", + "ru": "Список кодов локали, разделённых запятыми. Оставьте пустым, чтобы использовать глобальную конфигурацию.", + "ja": "カンマ区切りのロケールコードのリスト。グローバル設定を使用する場合は空欄のままにしてください。", + "de": "Durch Kommas getrennte Liste von Gebietsschemacodes. Leer lassen, um die globale Konfiguration zu verwenden." }, "createButton": { "source": "Create", "comment": "Create button text in create mode", "es": "Crear", - "fr-ca": "Créer" + "fr-ca": "Créer", + "ru": "Создавать", + "ja": "作成する", + "de": "Erstellen" }, "localesPlaceholder": { "source": "e.g., en, fr, es", "comment": "Placeholder text for locales input", "es": "ej., en, fr, es", - "fr-ca": "p. ex., en, fr, es" + "fr-ca": "p. ex., en, fr, es", + "ru": "например, en, fr, es", + "ja": "例:en、fr、es", + "de": "z.B. en, fr, es" }, "createTitle": { "source": "Create Collection", "es": "Crear Colección", - "fr-ca": "Créer une Collection" + "fr-ca": "Créer une Collection", + "ru": "Создать коллекцию", + "ja": "コレクションを作成する", + "de": "Sammlung erstellen" } } diff --git a/apps/tracker/src/i18n/collections/dialog/tracker_meta.json b/apps/tracker/src/i18n/collections/dialog/tracker_meta.json index 521aec75..b17b6c18 100644 --- a/apps/tracker/src/i18n/collections/dialog/tracker_meta.json +++ b/apps/tracker/src/i18n/collections/dialog/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "9b2e0addbf8c52f70c4f21afc6d04424", "baseChecksum": "8b8fc80765dd43c1c75c61077034b34e", "status": "new" + }, + "ru": { + "checksum": "f413c774d4c7f12fa4a133e70df40da7", + "baseChecksum": "8b8fc80765dd43c1c75c61077034b34e", + "status": "translated" + }, + "ja": { + "checksum": "b83a54fe9204ea7d0e91875385dea548", + "baseChecksum": "8b8fc80765dd43c1c75c61077034b34e", + "status": "translated" + }, + "de": { + "checksum": "4eb6b05d89f7d8b43824128653e737fb", + "baseChecksum": "8b8fc80765dd43c1c75c61077034b34e", + "status": "translated" } }, "namePlaceholder": { @@ -27,6 +42,21 @@ "checksum": "2f3f2ffc5064f3443abc44a2aa173875", "baseChecksum": "e02e22429e66e242217bdbbde92eb081", "status": "new" + }, + "ru": { + "checksum": "905b562f5dbea9c60fe502f92ef9f7ba", + "baseChecksum": "e02e22429e66e242217bdbbde92eb081", + "status": "translated" + }, + "ja": { + "checksum": "5eae9cb021611f848df6e197f9b888dd", + "baseChecksum": "e02e22429e66e242217bdbbde92eb081", + "status": "translated" + }, + "de": { + "checksum": "782f962a35e8cb15a981373e519011cf", + "baseChecksum": "e02e22429e66e242217bdbbde92eb081", + "status": "translated" } }, "nameRequired": { @@ -42,6 +72,21 @@ "checksum": "c3bc94f03a64aaa01c7f498608c466be", "baseChecksum": "c71ef39ab61feaed8cf0a058b3bd8acd", "status": "new" + }, + "ru": { + "checksum": "3ddda324919658f2bbbcc76b75f9aa18", + "baseChecksum": "c71ef39ab61feaed8cf0a058b3bd8acd", + "status": "translated" + }, + "ja": { + "checksum": "3875d242cda6eb205d6c87c2bd024d64", + "baseChecksum": "c71ef39ab61feaed8cf0a058b3bd8acd", + "status": "translated" + }, + "de": { + "checksum": "15903d83ea1c270f780a65adc3637b6b", + "baseChecksum": "c71ef39ab61feaed8cf0a058b3bd8acd", + "status": "translated" } }, "folderLabel": { @@ -57,6 +102,21 @@ "checksum": "f37e78057d928d7ad6d26fbdaf01a48a", "baseChecksum": "cec5a0934dba090c47144036ce5101ec", "status": "new" + }, + "ru": { + "checksum": "f69386fcfa4438d5c16063cda4e553c0", + "baseChecksum": "cec5a0934dba090c47144036ce5101ec", + "status": "translated" + }, + "ja": { + "checksum": "b4347be66c4ffab0558281d9700148c7", + "baseChecksum": "cec5a0934dba090c47144036ce5101ec", + "status": "translated" + }, + "de": { + "checksum": "e9aef33ec026993b01fdeffea7fa318e", + "baseChecksum": "cec5a0934dba090c47144036ce5101ec", + "status": "translated" } }, "folderPlaceholder": { @@ -72,6 +132,21 @@ "checksum": "276e83e426793d29498da9cb5318ff33", "baseChecksum": "f5baaa6df5e234ecbd095532b592a5e3", "status": "new" + }, + "ru": { + "checksum": "2054bcc0a9d2e4bd618a1940a77b9841", + "baseChecksum": "f5baaa6df5e234ecbd095532b592a5e3", + "status": "translated" + }, + "ja": { + "checksum": "8eb636b3b4cec411e91e81203fd101d5", + "baseChecksum": "f5baaa6df5e234ecbd095532b592a5e3", + "status": "translated" + }, + "de": { + "checksum": "5720c9d93a11e671bf1f5a314f1bc58f", + "baseChecksum": "f5baaa6df5e234ecbd095532b592a5e3", + "status": "translated" } }, "folderRequired": { @@ -87,6 +162,21 @@ "checksum": "dcb2957fece9aa9124e57ad9b85f5e27", "baseChecksum": "ccdc7033c15a7080fa1e47d82753e5da", "status": "new" + }, + "ru": { + "checksum": "d19d7edeff0e11f5d558af2888567da0", + "baseChecksum": "ccdc7033c15a7080fa1e47d82753e5da", + "status": "translated" + }, + "ja": { + "checksum": "9f4489246407c788ec401a626ca46cd9", + "baseChecksum": "ccdc7033c15a7080fa1e47d82753e5da", + "status": "translated" + }, + "de": { + "checksum": "c5c7ca80ec281a4e99cd8a1374296a8d", + "baseChecksum": "ccdc7033c15a7080fa1e47d82753e5da", + "status": "translated" } }, "localesLabel": { @@ -102,6 +192,21 @@ "checksum": "560244d0702fce943b9c7b6cb2d6bf1f", "baseChecksum": "978ddb4854a96b02f4d811f801f83ae3", "status": "new" + }, + "ru": { + "checksum": "51e92ed44afc8b2916ff528507039a05", + "baseChecksum": "978ddb4854a96b02f4d811f801f83ae3", + "status": "translated" + }, + "ja": { + "checksum": "79905421ba1e98994f4cb50c79665120", + "baseChecksum": "978ddb4854a96b02f4d811f801f83ae3", + "status": "translated" + }, + "de": { + "checksum": "ad081f3209715aa4783a02d40d0ec9ad", + "baseChecksum": "978ddb4854a96b02f4d811f801f83ae3", + "status": "translated" } }, "localesHint": { @@ -117,6 +222,21 @@ "checksum": "5ef803e770f90d2498d6a6e036df43ed", "baseChecksum": "a2e783531d2fcdcf61099aad5b0e55a8", "status": "new" + }, + "ru": { + "checksum": "8378c4bbbbcfcf9461b193618fa29297", + "baseChecksum": "a2e783531d2fcdcf61099aad5b0e55a8", + "status": "translated" + }, + "ja": { + "checksum": "e2f6d72247eff02a33466effbeae30b5", + "baseChecksum": "a2e783531d2fcdcf61099aad5b0e55a8", + "status": "translated" + }, + "de": { + "checksum": "a6d6d055412da5777830dda9d5166784", + "baseChecksum": "a2e783531d2fcdcf61099aad5b0e55a8", + "status": "translated" } }, "createButton": { @@ -132,6 +252,21 @@ "checksum": "205be9be7dda08c4608df07c0295340b", "baseChecksum": "686e697538050e4664636337cc3b834f", "status": "new" + }, + "ru": { + "checksum": "a0100b2077f85b2b147c6a93ee953756", + "baseChecksum": "686e697538050e4664636337cc3b834f", + "status": "translated" + }, + "ja": { + "checksum": "3af36172e4e95863b12b4734bc2472ed", + "baseChecksum": "686e697538050e4664636337cc3b834f", + "status": "translated" + }, + "de": { + "checksum": "9a08cb504f9ba9dc0a3075fee8aafca0", + "baseChecksum": "686e697538050e4664636337cc3b834f", + "status": "translated" } }, "localesPlaceholder": { @@ -147,6 +282,21 @@ "checksum": "6372844998585a033d8c4dfff24f0125", "baseChecksum": "b418a61851fec5c6ade8e4a34b907285", "status": "new" + }, + "ru": { + "checksum": "7ffe6d90c1ccf4183b4c42d3aef15dee", + "baseChecksum": "b418a61851fec5c6ade8e4a34b907285", + "status": "translated" + }, + "ja": { + "checksum": "de007e952695fb6243b28a8751f94f9e", + "baseChecksum": "b418a61851fec5c6ade8e4a34b907285", + "status": "translated" + }, + "de": { + "checksum": "1912e47149bcc738a7eb7a71d2ad1baa", + "baseChecksum": "b418a61851fec5c6ade8e4a34b907285", + "status": "translated" } }, "createTitle": { @@ -162,6 +312,21 @@ "checksum": "ede7465a10ac320690ce98a92a9515ce", "baseChecksum": "57c313ed48acfddf01bcbf4b3e4de556", "status": "new" + }, + "ru": { + "checksum": "f2758a5f11d0f14b901f83f75ca4b178", + "baseChecksum": "57c313ed48acfddf01bcbf4b3e4de556", + "status": "translated" + }, + "ja": { + "checksum": "5cc609a13047f3b1cb6388fd6e9583c1", + "baseChecksum": "57c313ed48acfddf01bcbf4b3e4de556", + "status": "translated" + }, + "de": { + "checksum": "8215c35839bdf9c5fe8379112e398fa7", + "baseChecksum": "57c313ed48acfddf01bcbf4b3e4de556", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/collections/emptyState/resource_entries.json b/apps/tracker/src/i18n/collections/emptyState/resource_entries.json index e9539446..e2d2e8cf 100644 --- a/apps/tracker/src/i18n/collections/emptyState/resource_entries.json +++ b/apps/tracker/src/i18n/collections/emptyState/resource_entries.json @@ -3,12 +3,18 @@ "source": "No collections yet", "comment": "Message shown when user has no collections", "es": "Aún no hay colecciones", - "fr-ca": "Aucune collection pour l'instant" + "fr-ca": "Aucune collection pour l'instant", + "ru": "Коллекций пока нет.", + "ja": "まだコレクションはありません", + "de": "Noch keine Sammlungen" }, "cta": { "source": "Create your first collection", "comment": "Call-to-action button in empty state to create first collection", "es": "Crea tu primera colección", - "fr-ca": "Créez votre première collection" + "fr-ca": "Créez votre première collection", + "ru": "Создайте свою первую коллекцию", + "ja": "最初のコレクションを作成する", + "de": "Erstelle deine erste Kollektion" } } diff --git a/apps/tracker/src/i18n/collections/emptyState/tracker_meta.json b/apps/tracker/src/i18n/collections/emptyState/tracker_meta.json index c1a38276..ec8eb4d4 100644 --- a/apps/tracker/src/i18n/collections/emptyState/tracker_meta.json +++ b/apps/tracker/src/i18n/collections/emptyState/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "48c6722c28f703c0dcf3134c8cb30156", "baseChecksum": "be7253840e621510212e49959ed1c8ad", "status": "new" + }, + "ru": { + "checksum": "17977a7157daae9f845b5147d189ea2e", + "baseChecksum": "be7253840e621510212e49959ed1c8ad", + "status": "translated" + }, + "ja": { + "checksum": "cefcc572a717a39f5379fbc5ac9805b6", + "baseChecksum": "be7253840e621510212e49959ed1c8ad", + "status": "translated" + }, + "de": { + "checksum": "74acd131136cdca46a8cdae6fec1d77b", + "baseChecksum": "be7253840e621510212e49959ed1c8ad", + "status": "translated" } }, "cta": { @@ -27,6 +42,21 @@ "checksum": "3bee4397201fc7e7bb847f6bea7ff859", "baseChecksum": "5532bcc75197c54314b36ba14e5a4ce5", "status": "new" + }, + "ru": { + "checksum": "e3c8236d95bb0ee4367024ec8f2e5b46", + "baseChecksum": "5532bcc75197c54314b36ba14e5a4ce5", + "status": "translated" + }, + "ja": { + "checksum": "0e7020409a0670e4d9055ac48b0f5f6f", + "baseChecksum": "5532bcc75197c54314b36ba14e5a4ce5", + "status": "translated" + }, + "de": { + "checksum": "8bf8edb0c95acaee5ef5d6ba7f1a25fd", + "baseChecksum": "5532bcc75197c54314b36ba14e5a4ce5", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/collections/form/errors/resource_entries.json b/apps/tracker/src/i18n/collections/form/errors/resource_entries.json index d6dd0fa6..43934eab 100644 --- a/apps/tracker/src/i18n/collections/form/errors/resource_entries.json +++ b/apps/tracker/src/i18n/collections/form/errors/resource_entries.json @@ -3,6 +3,9 @@ "source": "This field is required", "comment": "Validation error for required fields", "es": "Este campo es obligatorio", - "fr-ca": "Ce champ est requis" + "fr-ca": "Ce champ est requis", + "ru": "Это поле обязательно к заполнению", + "ja": "この項目は必須です", + "de": "Dieses Feld ist erforderlich" } } diff --git a/apps/tracker/src/i18n/collections/form/errors/tracker_meta.json b/apps/tracker/src/i18n/collections/form/errors/tracker_meta.json index 5d4663fc..154ea529 100644 --- a/apps/tracker/src/i18n/collections/form/errors/tracker_meta.json +++ b/apps/tracker/src/i18n/collections/form/errors/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "b56d54bd932dd0fae2f7e6862ede6ac7", "baseChecksum": "0511ee0d41117aa7b4abaaf102aa513d", "status": "new" + }, + "ru": { + "checksum": "0216d22927cb8af67c93b6e665c6d2a6", + "baseChecksum": "0511ee0d41117aa7b4abaaf102aa513d", + "status": "translated" + }, + "ja": { + "checksum": "a95cac41d531c7f117cf634dd6333166", + "baseChecksum": "0511ee0d41117aa7b4abaaf102aa513d", + "status": "translated" + }, + "de": { + "checksum": "dd79e75fe74ac6c80461f2cdd6f5195c", + "baseChecksum": "0511ee0d41117aa7b4abaaf102aa513d", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/collections/form/resource_entries.json b/apps/tracker/src/i18n/collections/form/resource_entries.json index e8b6bfa3..683d43ec 100644 --- a/apps/tracker/src/i18n/collections/form/resource_entries.json +++ b/apps/tracker/src/i18n/collections/form/resource_entries.json @@ -3,24 +3,36 @@ "source": "Collection name", "comment": "Label for collection name input field", "es": "Nombre de la colección", - "fr-ca": "Nom de la collection" + "fr-ca": "Nom de la collection", + "ru": "Название коллекции", + "ja": "コレクション名", + "de": "Sammlungsname" }, "translationsFolder": { "source": "Translations folder", "comment": "Label for translations folder path input field", "es": "Carpeta de traducciones", - "fr-ca": "Dossier de traductions" + "fr-ca": "Dossier de traductions", + "ru": "Папка «Переводы»", + "ja": "翻訳フォルダ", + "de": "Übersetzungsordner" }, "locales": { "source": "Locales", "comment": "Label for locales input field", "es": "Idiomas", - "fr-ca": "Langues" + "fr-ca": "Langues", + "ru": "Локалы", + "ja": "地域", + "de": "Orte" }, "localesPlaceholder": { "source": "Comma-separated (e.g., en,fr,es)", "comment": "Placeholder text showing format for locale input", "es": "Separados por comas (ej., en,fr,es)", - "fr-ca": "Séparés par des virgules (p. ex., en,fr,es)" + "fr-ca": "Séparés par des virgules (p. ex., en,fr,es)", + "ru": "Через запятую (например, en,fr,es)", + "ja": "カンマ区切り (例: en、fr、es)", + "de": "Durch Kommas getrennt (z. B. en,fr,es)" } } diff --git a/apps/tracker/src/i18n/collections/form/tracker_meta.json b/apps/tracker/src/i18n/collections/form/tracker_meta.json index 728ec648..08b3ca95 100644 --- a/apps/tracker/src/i18n/collections/form/tracker_meta.json +++ b/apps/tracker/src/i18n/collections/form/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "71a55f5613a683335f179aabae068dba", "baseChecksum": "3368b0851da49f06d4c69758cf85ac92", "status": "new" + }, + "ru": { + "checksum": "f413c774d4c7f12fa4a133e70df40da7", + "baseChecksum": "3368b0851da49f06d4c69758cf85ac92", + "status": "translated" + }, + "ja": { + "checksum": "b83a54fe9204ea7d0e91875385dea548", + "baseChecksum": "3368b0851da49f06d4c69758cf85ac92", + "status": "translated" + }, + "de": { + "checksum": "4eb6b05d89f7d8b43824128653e737fb", + "baseChecksum": "3368b0851da49f06d4c69758cf85ac92", + "status": "translated" } }, "translationsFolder": { @@ -27,6 +42,21 @@ "checksum": "1adaec0c3a5232d67a57d9be21d6986f", "baseChecksum": "da38f56b09a32e7328c23c01f0a0738e", "status": "new" + }, + "ru": { + "checksum": "707cdce5f3be49e5ac8ab4d6a87bb519", + "baseChecksum": "da38f56b09a32e7328c23c01f0a0738e", + "status": "translated" + }, + "ja": { + "checksum": "b4347be66c4ffab0558281d9700148c7", + "baseChecksum": "da38f56b09a32e7328c23c01f0a0738e", + "status": "translated" + }, + "de": { + "checksum": "e9aef33ec026993b01fdeffea7fa318e", + "baseChecksum": "da38f56b09a32e7328c23c01f0a0738e", + "status": "translated" } }, "locales": { @@ -42,6 +72,21 @@ "checksum": "1ea21417b4fc870a18d6a244983be72b", "baseChecksum": "52ec7aab68a6cdc237d9db8133bc815f", "status": "new" + }, + "ru": { + "checksum": "9178af860bce312048c5866c8f386f00", + "baseChecksum": "52ec7aab68a6cdc237d9db8133bc815f", + "status": "translated" + }, + "ja": { + "checksum": "4d7d4410dab75a44ad27b57e84dc1aac", + "baseChecksum": "52ec7aab68a6cdc237d9db8133bc815f", + "status": "translated" + }, + "de": { + "checksum": "feb6c21898b72670be6296ec7ccb2dc2", + "baseChecksum": "52ec7aab68a6cdc237d9db8133bc815f", + "status": "translated" } }, "localesPlaceholder": { @@ -57,6 +102,21 @@ "checksum": "0ecdcd628ee785eca45aaccef0413f35", "baseChecksum": "43735cf0e646ed6cb9f4863c9120e09d", "status": "new" + }, + "ru": { + "checksum": "dab66c93ccf68c9c3c50bb597c026753", + "baseChecksum": "43735cf0e646ed6cb9f4863c9120e09d", + "status": "translated" + }, + "ja": { + "checksum": "cb103d2acc95ffab118d3cfe6ed11df3", + "baseChecksum": "43735cf0e646ed6cb9f4863c9120e09d", + "status": "translated" + }, + "de": { + "checksum": "585c73045552d5fb59ae9311af1a882e", + "baseChecksum": "43735cf0e646ed6cb9f4863c9120e09d", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/collections/resource_entries.json b/apps/tracker/src/i18n/collections/resource_entries.json index 798d4655..1621ba8d 100644 --- a/apps/tracker/src/i18n/collections/resource_entries.json +++ b/apps/tracker/src/i18n/collections/resource_entries.json @@ -3,12 +3,18 @@ "source": "Collections", "comment": "Page title for collections management dashboard", "es": "Colecciones", - "fr-ca": "Collections" + "fr-ca": "Collections", + "ru": "Коллекции", + "ja": "コレクション", + "de": "Sammlungen" }, "addButton": { "source": "Add Collection", "comment": "Button text to open dialog for creating a new collection", "es": "Agregar Colección", - "fr-ca": "Ajouter une Collection" + "fr-ca": "Ajouter une Collection", + "ru": "Добавить коллекцию", + "ja": "コレクションを追加", + "de": "Sammlung hinzufügen" } } diff --git a/apps/tracker/src/i18n/collections/toast/resource_entries.json b/apps/tracker/src/i18n/collections/toast/resource_entries.json index 35980fc1..b3e2041a 100644 --- a/apps/tracker/src/i18n/collections/toast/resource_entries.json +++ b/apps/tracker/src/i18n/collections/toast/resource_entries.json @@ -3,52 +3,76 @@ "source": "Collection created successfully", "comment": "Success message after creating a collection", "es": "Colección creada exitosamente", - "fr-ca": "Collection créée avec succès" + "fr-ca": "Collection créée avec succès", + "ru": "Коллекция успешно создана.", + "ja": "コレクションが正常に作成されました", + "de": "Sammlung erfolgreich erstellt" }, "updated": { "source": "Collection updated successfully", "comment": "Success message after editing a collection", "es": "Colección actualizada exitosamente", - "fr-ca": "Collection mise à jour avec succès" + "fr-ca": "Collection mise à jour avec succès", + "ru": "Коллекция успешно обновлена.", + "ja": "コレクションが正常に更新されました", + "de": "Sammlung erfolgreich aktualisiert" }, "deleted": { "source": "Collection deleted successfully", "comment": "Success message after deleting a collection", "es": "Colección eliminada exitosamente", - "fr-ca": "Collection supprimée avec succès" + "fr-ca": "Collection supprimée avec succès", + "ru": "Коллекция успешно удалена.", + "ja": "コレクションは正常に削除されました", + "de": "Sammlung erfolgreich gelöscht" }, "error": { "source": "An error occurred. Please try again.", "comment": "Generic error message for failed operations", "es": "Ocurrió un error. Por favor, inténtalo de nuevo.", - "fr-ca": "Une erreur s'est produite. Veuillez réessayer." + "fr-ca": "Une erreur s'est produite. Veuillez réessayer.", + "ru": "Произошла ошибка. Пожалуйста, попробуйте еще раз.", + "ja": "エラーが発生しました。もう一度お試しください。", + "de": "Es ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut." }, "loadFailed": { "source": "Failed to load collections", "comment": "Error toast when loading collections fails", "tags": ["collections"], "es": "No se pudieron cargar las colecciones", - "fr-ca": "Échec du chargement des collections" + "fr-ca": "Échec du chargement des collections", + "ru": "Не удалось загрузить коллекции.", + "ja": "コレクションの読み込みに失敗しました", + "de": "Sammlungen konnten nicht geladen werden" }, "createFailed": { "source": "Failed to create collection", "comment": "Error toast when creating a collection fails", "tags": ["collections"], "es": "No se pudo crear la colección", - "fr-ca": "Impossible de créer la collection" + "fr-ca": "Impossible de créer la collection", + "ru": "Не удалось создать коллекцию.", + "ja": "コレクションの作成に失敗しました", + "de": "Sammlung konnte nicht erstellt werden" }, "updateFailed": { "source": "Failed to update collection", "comment": "Error toast when updating a collection fails", "tags": ["collections"], "es": "No se pudo actualizar la colección", - "fr-ca": "Échec de la mise à jour de la collection" + "fr-ca": "Échec de la mise à jour de la collection", + "ru": "Не удалось обновить коллекцию.", + "ja": "コレクションの更新に失敗しました", + "de": "Aktualisierung der Sammlung fehlgeschlagen" }, "deleteFailed": { "source": "Failed to delete collection", "comment": "Error toast when deleting a collection fails", "tags": ["collections"], "es": "No se pudo eliminar la colección", - "fr-ca": "Échec de la suppression de la collection" + "fr-ca": "Échec de la suppression de la collection", + "ru": "Не удалось удалить коллекцию.", + "ja": "コレクションの削除に失敗しました", + "de": "Sammlung konnte nicht gelöscht werden" } } diff --git a/apps/tracker/src/i18n/collections/toast/tracker_meta.json b/apps/tracker/src/i18n/collections/toast/tracker_meta.json index 42cac44d..8d3c48e4 100644 --- a/apps/tracker/src/i18n/collections/toast/tracker_meta.json +++ b/apps/tracker/src/i18n/collections/toast/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "f0c46edea5b3228182d4bd2a8526d41c", "baseChecksum": "3ff499a5a5250bc268afb3a949a0f371", "status": "new" + }, + "ru": { + "checksum": "a2c6e00d4666f43c732eac744c3a6de4", + "baseChecksum": "3ff499a5a5250bc268afb3a949a0f371", + "status": "translated" + }, + "ja": { + "checksum": "b650f261e0a6872a640c8c10c93bf8a0", + "baseChecksum": "3ff499a5a5250bc268afb3a949a0f371", + "status": "translated" + }, + "de": { + "checksum": "183a3e5259df641d1bc2138f3767ff6e", + "baseChecksum": "3ff499a5a5250bc268afb3a949a0f371", + "status": "translated" } }, "updated": { @@ -27,6 +42,21 @@ "checksum": "229631219826952bae7825d648a129c9", "baseChecksum": "16cabd5255794b8a7f11a1015879d22e", "status": "new" + }, + "ru": { + "checksum": "9416053d46ee2878a0dd68a37cc8315e", + "baseChecksum": "16cabd5255794b8a7f11a1015879d22e", + "status": "translated" + }, + "ja": { + "checksum": "daaf1ba1d63c59b9160997072e0fbc55", + "baseChecksum": "16cabd5255794b8a7f11a1015879d22e", + "status": "translated" + }, + "de": { + "checksum": "c383b909b76e97fbbc02585c1e2a5ffe", + "baseChecksum": "16cabd5255794b8a7f11a1015879d22e", + "status": "translated" } }, "deleted": { @@ -42,6 +72,21 @@ "checksum": "700ae16628d36c1192dcf0599e14161d", "baseChecksum": "bc2e2ad82c57023153745544ddc56f00", "status": "new" + }, + "ru": { + "checksum": "fa821a55c33c9ccfe0abde0c039d98e3", + "baseChecksum": "bc2e2ad82c57023153745544ddc56f00", + "status": "translated" + }, + "ja": { + "checksum": "5c93177892f1b2948ecf5b4d2dab876a", + "baseChecksum": "bc2e2ad82c57023153745544ddc56f00", + "status": "translated" + }, + "de": { + "checksum": "37bf1db339352f6ed59e85867c2e43ad", + "baseChecksum": "bc2e2ad82c57023153745544ddc56f00", + "status": "translated" } }, "error": { @@ -57,6 +102,21 @@ "checksum": "9870ec90fee1aba84a4990f1edcea33a", "baseChecksum": "b028ccd04708b8c3c7722956e149a718", "status": "new" + }, + "ru": { + "checksum": "01480858a5404da77d5aa893ea7926f5", + "baseChecksum": "b028ccd04708b8c3c7722956e149a718", + "status": "translated" + }, + "ja": { + "checksum": "bdaf2e4efb9178f2fb916518f06e7326", + "baseChecksum": "b028ccd04708b8c3c7722956e149a718", + "status": "translated" + }, + "de": { + "checksum": "0aa38a7138f1c92ed1759807e1f1e25f", + "baseChecksum": "b028ccd04708b8c3c7722956e149a718", + "status": "translated" } }, "loadFailed": { @@ -72,6 +132,21 @@ "checksum": "946a6b6d2a9aa580f76aff594ab251ed", "baseChecksum": "3cd53d5bd22a26c0e6d7b8b9b80256bc", "status": "translated" + }, + "ru": { + "checksum": "9f7cd6b4931a75e4235408e7bdfdb494", + "baseChecksum": "3cd53d5bd22a26c0e6d7b8b9b80256bc", + "status": "translated" + }, + "ja": { + "checksum": "f46e0f86b255430967d68a5d391b6106", + "baseChecksum": "3cd53d5bd22a26c0e6d7b8b9b80256bc", + "status": "translated" + }, + "de": { + "checksum": "66e247fedb619d3b232f973a55ed3628", + "baseChecksum": "3cd53d5bd22a26c0e6d7b8b9b80256bc", + "status": "translated" } }, "createFailed": { @@ -87,6 +162,21 @@ "checksum": "18a29481584edbea016b424941562d95", "baseChecksum": "d4f390c01f513602c9b62bc7fd16f640", "status": "translated" + }, + "ru": { + "checksum": "f73849f7f695c0b7fffeafec0b211e23", + "baseChecksum": "d4f390c01f513602c9b62bc7fd16f640", + "status": "translated" + }, + "ja": { + "checksum": "513eda515bff76ffcd9df10bfdf79194", + "baseChecksum": "d4f390c01f513602c9b62bc7fd16f640", + "status": "translated" + }, + "de": { + "checksum": "d3c701644953405179d2e5c57b0d9084", + "baseChecksum": "d4f390c01f513602c9b62bc7fd16f640", + "status": "translated" } }, "updateFailed": { @@ -102,6 +192,21 @@ "checksum": "925e9bb8f2574f47c6dac64472fcf85b", "baseChecksum": "af9daa27991b1108df98277da9d19a38", "status": "translated" + }, + "ru": { + "checksum": "6c6688811503d773644f8d390ddf8b32", + "baseChecksum": "af9daa27991b1108df98277da9d19a38", + "status": "translated" + }, + "ja": { + "checksum": "977fd75103172c06892875afadf0fe52", + "baseChecksum": "af9daa27991b1108df98277da9d19a38", + "status": "translated" + }, + "de": { + "checksum": "6617b4a1e68fbd45200dabdd5a63b721", + "baseChecksum": "af9daa27991b1108df98277da9d19a38", + "status": "translated" } }, "deleteFailed": { @@ -117,6 +222,21 @@ "checksum": "0a24bee9edc2d6eddb79efe6a0fc8419", "baseChecksum": "a3a3dbfef848fa5e2f561b1903456577", "status": "translated" + }, + "ru": { + "checksum": "427da9de524038ca6370fac8b9fa22c9", + "baseChecksum": "a3a3dbfef848fa5e2f561b1903456577", + "status": "translated" + }, + "ja": { + "checksum": "5ad4e477c870d876c22be03b8c5b1beb", + "baseChecksum": "a3a3dbfef848fa5e2f561b1903456577", + "status": "translated" + }, + "de": { + "checksum": "0de84cf537f9d69eda4432e5c928fdad", + "baseChecksum": "a3a3dbfef848fa5e2f561b1903456577", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/collections/tracker_meta.json b/apps/tracker/src/i18n/collections/tracker_meta.json index c80a1f3d..b3add7e3 100644 --- a/apps/tracker/src/i18n/collections/tracker_meta.json +++ b/apps/tracker/src/i18n/collections/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "a9fc91939a389c7c73e7a3f3cbf411cd", "baseChecksum": "a9fc91939a389c7c73e7a3f3cbf411cd", "status": "new" + }, + "ru": { + "checksum": "306e41fce3bc9de4911363df9a80a5ba", + "baseChecksum": "a9fc91939a389c7c73e7a3f3cbf411cd", + "status": "translated" + }, + "ja": { + "checksum": "695b82464aee401b828677a0100f6cba", + "baseChecksum": "a9fc91939a389c7c73e7a3f3cbf411cd", + "status": "translated" + }, + "de": { + "checksum": "18c4b3ff903711a9bd98c54cacb132a2", + "baseChecksum": "a9fc91939a389c7c73e7a3f3cbf411cd", + "status": "translated" } }, "addButton": { @@ -27,6 +42,21 @@ "checksum": "8415e183eef3d657a530bbd6c1fb5ef0", "baseChecksum": "10ac958235fe83036f8e5244454f7c78", "status": "new" + }, + "ru": { + "checksum": "8e290a022048d2cf84f456d1170ce6aa", + "baseChecksum": "10ac958235fe83036f8e5244454f7c78", + "status": "translated" + }, + "ja": { + "checksum": "0404adec384698dfde5bf4e317661742", + "baseChecksum": "10ac958235fe83036f8e5244454f7c78", + "status": "translated" + }, + "de": { + "checksum": "88e8e83cfb5d7e109e7f4e65ed345d73", + "baseChecksum": "10ac958235fe83036f8e5244454f7c78", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/common/actions/resource_entries.json b/apps/tracker/src/i18n/common/actions/resource_entries.json index 4fc0b54e..bcdc625f 100644 --- a/apps/tracker/src/i18n/common/actions/resource_entries.json +++ b/apps/tracker/src/i18n/common/actions/resource_entries.json @@ -4,90 +4,132 @@ "comment": "Text on a button or link that will display edit form for an entity", "tags": ["common"], "es": "Editar", - "fr-ca": "Modifier" + "fr-ca": "Modifier", + "ru": "Редактировать", + "ja": "編集", + "de": "Bearbeiten" }, "delete": { "source": "Delete", "comment": "Text on a button that will cause an entity to be deleted", "tags": ["common"], "es": "Eliminar", - "fr-ca": "Supprimer" + "fr-ca": "Supprimer", + "ru": "Удалить", + "ja": "消去", + "de": "Löschen" }, "retry": { "source": "Retry", "comment": "Text on a button to cause an action to retry operation", "tags": ["common"], "es": "Reintentar", - "fr-ca": "Réessayer" + "fr-ca": "Réessayer", + "ru": "Повторить попытку", + "ja": "リトライ", + "de": "Wiederholen" }, "cancel": { "source": "Cancel", "comment": "Text on a button to cancel whatever opration the user was about to do", "es": "Cancelar", - "fr-ca": "Annuler" + "fr-ca": "Annuler", + "ru": "Отмена", + "ja": "キャンセル", + "de": "Stornieren" }, "ok": { "source": "OK", "es": "OK", - "fr-ca": "OK" + "fr-ca": "OK", + "ru": "ХОРОШО", + "ja": "わかりました", + "de": "OK" }, "save": { "source": "Save", "comment": "Save button text in edit mode", "es": "Guardar", - "fr-ca": "Enregistrer" + "fr-ca": "Enregistrer", + "ru": "Сохранять", + "ja": "保存", + "de": "Speichern" }, "back": { "source": "Back", "es": "Volver", - "fr-ca": "Retour" + "fr-ca": "Retour", + "ru": "Назад", + "ja": "戻る", + "de": "Zurück" }, "clickToCopy": { "source": "click to copy", "comment": "Message to user that item can be copied to clipboard", "es": "clic para copiar", - "fr-ca": "cliquer pour copier" + "fr-ca": "cliquer pour copier", + "ru": "нажмите, чтобы скопировать", + "ja": "クリックしてコピー", + "de": "Zum Kopieren klicken" }, "move": { "source": "Move", "comment": "Action label to move an item to a different location", "tags": ["common"], "es": "Mover", - "fr-ca": "Déplacer" + "fr-ca": "Déplacer", + "ru": "Двигаться", + "ja": "動く", + "de": "Bewegen" }, "translate": { "source": "Translate", "comment": "Action button to auto-translate a resource", "tags": ["common"], "es": "Traducir", - "fr-ca": "Traduire" + "fr-ca": "Traduire", + "ru": "Переводить", + "ja": "翻訳する", + "de": "Übersetzen" }, "selectAll": { "source": "Select All", "comment": "Button to select all items in a list or filter", "tags": ["common"], "es": "Seleccionar todo", - "fr-ca": "Sélectionner tout" + "fr-ca": "Sélectionner tout", + "ru": "Выбрать все", + "ja": "すべて選択", + "de": "Alle auswählen" }, "clearAll": { "source": "Clear All", "comment": "Button to clear all selections in a list or filter", "tags": ["common"], "es": "Borrar todo", - "fr-ca": "Effacer tout" + "fr-ca": "Effacer tout", + "ru": "Очистить все", + "ja": "すべてクリア", + "de": "Alles löschen" }, "close": { "source": "Close", "comment": "Button to close a dialog or dismiss a notification", "tags": ["common"], "es": "Cerca", - "fr-ca": "Fermer" + "fr-ca": "Fermer", + "ru": "Закрывать", + "ja": "近い", + "de": "Schließen" }, "dismiss": { "source": "Dismiss", "comment": "Button to dismiss a notification or snackbar", "tags": ["common"], "es": "Despedir", - "fr-ca": "Rejeter" + "fr-ca": "Rejeter", + "ru": "Увольнять", + "ja": "却下する", + "de": "Zurückweisen" } } diff --git a/apps/tracker/src/i18n/common/actions/tracker_meta.json b/apps/tracker/src/i18n/common/actions/tracker_meta.json index 16f7e139..a378af48 100644 --- a/apps/tracker/src/i18n/common/actions/tracker_meta.json +++ b/apps/tracker/src/i18n/common/actions/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "898c079d2e62a4b1971dfbad9d860838", "baseChecksum": "7dce122004969d56ae2e0245cb754d35", "status": "new" + }, + "ru": { + "checksum": "1706282c5244c8e988f76c5eb939b754", + "baseChecksum": "7dce122004969d56ae2e0245cb754d35", + "status": "translated" + }, + "ja": { + "checksum": "7578865c9404415b6a4e2d6d3294f590", + "baseChecksum": "7dce122004969d56ae2e0245cb754d35", + "status": "translated" + }, + "de": { + "checksum": "5ad05dd4fa8fe82c3a85570683c368ad", + "baseChecksum": "7dce122004969d56ae2e0245cb754d35", + "status": "translated" } }, "delete": { @@ -27,6 +42,21 @@ "checksum": "ccfd9851b50aaa671513b50d158ed579", "baseChecksum": "f2a6c498fb90ee345d997f888fce3b18", "status": "new" + }, + "ru": { + "checksum": "ed2bbfbc53d83d3ad81f7fd6485ac6e8", + "baseChecksum": "f2a6c498fb90ee345d997f888fce3b18", + "status": "translated" + }, + "ja": { + "checksum": "e3fdb571cbafd9894cb80a2a2c95f342", + "baseChecksum": "f2a6c498fb90ee345d997f888fce3b18", + "status": "translated" + }, + "de": { + "checksum": "1010b01ca33474b21dfca7411a13552c", + "baseChecksum": "f2a6c498fb90ee345d997f888fce3b18", + "status": "translated" } }, "retry": { @@ -42,6 +72,21 @@ "checksum": "ed7abe3ce03a238f04222a1eec48f1f5", "baseChecksum": "6327b4e59f58137083214a1fec358855", "status": "new" + }, + "ru": { + "checksum": "e791d60a16de757b90bb404911991ea4", + "baseChecksum": "6327b4e59f58137083214a1fec358855", + "status": "translated" + }, + "ja": { + "checksum": "a19b46385fb285a0c55d8e1e2f6e8ce3", + "baseChecksum": "6327b4e59f58137083214a1fec358855", + "status": "translated" + }, + "de": { + "checksum": "dc0462575ab372239bcfd43a81cbc51f", + "baseChecksum": "6327b4e59f58137083214a1fec358855", + "status": "translated" } }, "cancel": { @@ -57,6 +102,21 @@ "checksum": "d12c3b0dcf75614dafb2ac6bdaa77a26", "baseChecksum": "ea4788705e6873b424c65e91c2846b19", "status": "new" + }, + "ru": { + "checksum": "987b33c664dce148f1d17f6eb9ab3e79", + "baseChecksum": "ea4788705e6873b424c65e91c2846b19", + "status": "translated" + }, + "ja": { + "checksum": "6ef34982969f60212f6f2565454d7beb", + "baseChecksum": "ea4788705e6873b424c65e91c2846b19", + "status": "translated" + }, + "de": { + "checksum": "6cc04dc1f419c8b2f1b28303ab0bec49", + "baseChecksum": "ea4788705e6873b424c65e91c2846b19", + "status": "translated" } }, "ok": { @@ -72,6 +132,21 @@ "checksum": "e0aa021e21dddbd6d8cecec71e9cf564", "baseChecksum": "e0aa021e21dddbd6d8cecec71e9cf564", "status": "new" + }, + "ru": { + "checksum": "3094fd4ad571cc9b65de310d2164b5b0", + "baseChecksum": "e0aa021e21dddbd6d8cecec71e9cf564", + "status": "translated" + }, + "ja": { + "checksum": "ad7a978ba733087c977b4edbda8ace9a", + "baseChecksum": "e0aa021e21dddbd6d8cecec71e9cf564", + "status": "translated" + }, + "de": { + "checksum": "e0aa021e21dddbd6d8cecec71e9cf564", + "baseChecksum": "e0aa021e21dddbd6d8cecec71e9cf564", + "status": "translated" } }, "save": { @@ -87,6 +162,21 @@ "checksum": "aed88202e2432ee2a613f9120ef7486b", "baseChecksum": "c9cc8cce247e49bae79f15173ce97354", "status": "new" + }, + "ru": { + "checksum": "9ef62ebfb3ea5b3a1a4901f15142efae", + "baseChecksum": "c9cc8cce247e49bae79f15173ce97354", + "status": "translated" + }, + "ja": { + "checksum": "be5fbbe34ce9979bfb6576d9eddc5612", + "baseChecksum": "c9cc8cce247e49bae79f15173ce97354", + "status": "translated" + }, + "de": { + "checksum": "b97d23bf800ff592f7afe97a29921271", + "baseChecksum": "c9cc8cce247e49bae79f15173ce97354", + "status": "translated" } }, "back": { @@ -102,6 +192,21 @@ "checksum": "7727eb7488be3ef30da590f1f667181e", "baseChecksum": "0557fa923dcee4d0f86b1409f5c2167f", "status": "new" + }, + "ru": { + "checksum": "2b0b0225a86bb67048840d3da9b899bc", + "baseChecksum": "0557fa923dcee4d0f86b1409f5c2167f", + "status": "translated" + }, + "ja": { + "checksum": "4a622f127baeae041b4eef6a8884069f", + "baseChecksum": "0557fa923dcee4d0f86b1409f5c2167f", + "status": "translated" + }, + "de": { + "checksum": "429bdf7fb1ab9dd6ff5f8f5b6d380968", + "baseChecksum": "0557fa923dcee4d0f86b1409f5c2167f", + "status": "translated" } }, "clickToCopy": { @@ -117,6 +222,21 @@ "checksum": "abe872e54b785c715e340a066cf0dddf", "baseChecksum": "b8ac6182757b167c8f10fd8806b9bc27", "status": "new" + }, + "ru": { + "checksum": "e62609fc5e015317c78fbbf228b9a778", + "baseChecksum": "b8ac6182757b167c8f10fd8806b9bc27", + "status": "translated" + }, + "ja": { + "checksum": "721b61c6ae82cf3d023ceb55d7dd9c7e", + "baseChecksum": "b8ac6182757b167c8f10fd8806b9bc27", + "status": "translated" + }, + "de": { + "checksum": "67aedde6709e2f1d0660833677ab0e58", + "baseChecksum": "b8ac6182757b167c8f10fd8806b9bc27", + "status": "translated" } }, "move": { @@ -132,6 +252,21 @@ "checksum": "d7f3edbd8fd82a7d4d5a722dbbe36dc8", "baseChecksum": "6bc362dbf494c61ea117fe3c71ca48a5", "status": "new" + }, + "ru": { + "checksum": "1ce26faf65044371b40bd95cbb5c3a69", + "baseChecksum": "6bc362dbf494c61ea117fe3c71ca48a5", + "status": "translated" + }, + "ja": { + "checksum": "db9c1f7b49105fffe513bdc9cbda744f", + "baseChecksum": "6bc362dbf494c61ea117fe3c71ca48a5", + "status": "translated" + }, + "de": { + "checksum": "a8b34245fdc001a2f5432f12601bb7e0", + "baseChecksum": "6bc362dbf494c61ea117fe3c71ca48a5", + "status": "translated" } }, "translate": { @@ -147,6 +282,21 @@ "checksum": "608b1b1fed86319b97f5c65b0fda9b5d", "baseChecksum": "deccbe4e9083c3b5f7cd2632722765bb", "status": "translated" + }, + "ru": { + "checksum": "f80abd27695cafd474055fcf84d161c4", + "baseChecksum": "deccbe4e9083c3b5f7cd2632722765bb", + "status": "translated" + }, + "ja": { + "checksum": "c3a5d2da2ad33221043d5a6992f5f409", + "baseChecksum": "deccbe4e9083c3b5f7cd2632722765bb", + "status": "translated" + }, + "de": { + "checksum": "c59cefbcfba7b00b96d89f1efaec9aed", + "baseChecksum": "deccbe4e9083c3b5f7cd2632722765bb", + "status": "translated" } }, "selectAll": { @@ -162,6 +312,21 @@ "checksum": "444c87852bd465ff516372130cdbab62", "baseChecksum": "45e96c0a422ce8a1a6ec1bd5eb9625c6", "status": "translated" + }, + "ru": { + "checksum": "4d09821e5f0ae6b496ac3211da10f88b", + "baseChecksum": "45e96c0a422ce8a1a6ec1bd5eb9625c6", + "status": "translated" + }, + "ja": { + "checksum": "ab0e66f073d4d8aff7c49ff0bf2437a6", + "baseChecksum": "45e96c0a422ce8a1a6ec1bd5eb9625c6", + "status": "translated" + }, + "de": { + "checksum": "f687cca4add06ebc15712a4f20f357be", + "baseChecksum": "45e96c0a422ce8a1a6ec1bd5eb9625c6", + "status": "translated" } }, "clearAll": { @@ -177,6 +342,21 @@ "checksum": "d34c9c47ced7d0d930e781495194fa3c", "baseChecksum": "e77fef0167598bb39846637ac3915f4e", "status": "translated" + }, + "ru": { + "checksum": "60e71159f846d33df09e27565f81dea6", + "baseChecksum": "e77fef0167598bb39846637ac3915f4e", + "status": "translated" + }, + "ja": { + "checksum": "ec00a6332860c1cdbe7e5307d05acfdd", + "baseChecksum": "e77fef0167598bb39846637ac3915f4e", + "status": "translated" + }, + "de": { + "checksum": "b2031bb0236d90f8842472690156b040", + "baseChecksum": "e77fef0167598bb39846637ac3915f4e", + "status": "translated" } }, "close": { @@ -192,6 +372,21 @@ "checksum": "7d206237f9912ea010005db2c20b60ce", "baseChecksum": "d3d2e617335f08df83599665eef8a418", "status": "translated" + }, + "ru": { + "checksum": "08969efbfd249fd88df5db4464118740", + "baseChecksum": "d3d2e617335f08df83599665eef8a418", + "status": "translated" + }, + "ja": { + "checksum": "3dd21923aef0993456c21da79102b8e1", + "baseChecksum": "d3d2e617335f08df83599665eef8a418", + "status": "translated" + }, + "de": { + "checksum": "8311b9b64370db830145f6612a9021fd", + "baseChecksum": "d3d2e617335f08df83599665eef8a418", + "status": "translated" } }, "dismiss": { @@ -207,6 +402,21 @@ "checksum": "9757a390d15b48413b06d6469d8b36cd", "baseChecksum": "c8a59e7135a20b362f9c768b09454fdb", "status": "translated" + }, + "ru": { + "checksum": "9e6d70043b0014003f34e770dea3985b", + "baseChecksum": "c8a59e7135a20b362f9c768b09454fdb", + "status": "translated" + }, + "ja": { + "checksum": "0d53c36ecff639eae2f8283109fa1f3f", + "baseChecksum": "c8a59e7135a20b362f9c768b09454fdb", + "status": "translated" + }, + "de": { + "checksum": "3275660758a8f2dc513c09aaa869cff2", + "baseChecksum": "c8a59e7135a20b362f9c768b09454fdb", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/data/resource_entries.json b/apps/tracker/src/i18n/data/resource_entries.json index 8453cf11..34efd784 100644 --- a/apps/tracker/src/i18n/data/resource_entries.json +++ b/apps/tracker/src/i18n/data/resource_entries.json @@ -4,6 +4,9 @@ "comment": "Message shown while data is loading", "tags": ["data"], "es": "Cargando", - "fr-ca": "Chargement" + "fr-ca": "Chargement", + "ru": "Загрузка", + "ja": "ロード中", + "de": "Laden" } } diff --git a/apps/tracker/src/i18n/data/tracker_meta.json b/apps/tracker/src/i18n/data/tracker_meta.json index c172d6b4..d3f963c6 100644 --- a/apps/tracker/src/i18n/data/tracker_meta.json +++ b/apps/tracker/src/i18n/data/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "2f9c752cf48e056f11e3a7c1ff886422", "baseChecksum": "16bfbf9c462762cf1cba4134ec53c504", "status": "new" + }, + "ru": { + "checksum": "2cadf42b2a044fe2b3c8e7574d845867", + "baseChecksum": "16bfbf9c462762cf1cba4134ec53c504", + "status": "translated" + }, + "ja": { + "checksum": "8c00614cba8a72708e294877d21408da", + "baseChecksum": "16bfbf9c462762cf1cba4134ec53c504", + "status": "translated" + }, + "de": { + "checksum": "18f6ee15e59ad9647428c059344d67d3", + "baseChecksum": "16bfbf9c462762cf1cba4134ec53c504", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/header/resource_entries.json b/apps/tracker/src/i18n/header/resource_entries.json index 1a2e0c8d..a8885950 100644 --- a/apps/tracker/src/i18n/header/resource_entries.json +++ b/apps/tracker/src/i18n/header/resource_entries.json @@ -4,27 +4,39 @@ "comment": "Aria-label and tooltip for the brand link in the app header", "tags": ["header"], "es": "Ir a Colecciones", - "fr-ca": "Accéder aux collections" + "fr-ca": "Accéder aux collections", + "ru": "Перейти в Коллекции", + "ja": "コレクションへ移動", + "de": "Zu den Sammlungen" }, "backToCollections": { "source": "Back to Collections", "comment": "Aria-label and tooltip for the back button in the app header when viewing a collection", "tags": ["header"], "es": "Volver a Colecciones", - "fr-ca": "Retour aux collections" + "fr-ca": "Retour aux collections", + "ru": "Вернуться к коллекциям", + "ja": "コレクション一覧に戻る", + "de": "Zurück zu den Sammlungen" }, "keysCountX": { "source": "{ count, plural, =1 {1 key} other {{count} keys} }", "comment": "Pluralized count of translation keys shown in the app header stats", "tags": ["header"], "es": "{ count, plural, =1 {1 key} other {{count} keys} }", - "fr-ca": "{ count, plural, =1 {1 key} other {{count} keys} }" + "fr-ca": "{ count, plural, =1 {1 key} other {{count} keys} }", + "ru": "{ count, plural, =1 {1 key} other {{count} keys} }", + "ja": "{ count, plural, =1 {1 key} other {{count} keys} }", + "de": "{ count, plural, =1 {1 key} other {{count} keys} }" }, "localesCountX": { "source": "{ count, plural, =1 {1 locale} other {{count} locales} }", "comment": "Pluralized count of locales shown in the app header stats", "tags": ["header"], "es": "{ count, plural, =1 {1 locale} other {{count} locales} }", - "fr-ca": "{ count, plural, =1 {1 locale} other {{count} locales} }" + "fr-ca": "{ count, plural, =1 {1 locale} other {{count} locales} }", + "ru": "{ count, plural, =1 {1 locale} other {{count} locales} }", + "ja": "{ count, plural, =1 {1 locale} other {{count} locales} }", + "de": "{ count, plural, =1 {1 locale} other {{count} locales} }" } } diff --git a/apps/tracker/src/i18n/header/tracker_meta.json b/apps/tracker/src/i18n/header/tracker_meta.json index fa0addc9..5e3ecdb4 100644 --- a/apps/tracker/src/i18n/header/tracker_meta.json +++ b/apps/tracker/src/i18n/header/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "bd6e679d65eb7508feac07a4a808906b", "baseChecksum": "e7926ae5bb733a6f509ed9e6d7e88245", "status": "translated" + }, + "ru": { + "checksum": "7dde960bec7839181d20fc35537bf20a", + "baseChecksum": "e7926ae5bb733a6f509ed9e6d7e88245", + "status": "translated" + }, + "ja": { + "checksum": "73838d09ad1021c2c5926edcf3562640", + "baseChecksum": "e7926ae5bb733a6f509ed9e6d7e88245", + "status": "translated" + }, + "de": { + "checksum": "4fd854ad1afc03082574586c9174d727", + "baseChecksum": "e7926ae5bb733a6f509ed9e6d7e88245", + "status": "translated" } }, "backToCollections": { @@ -27,6 +42,21 @@ "checksum": "73586b8c21ceaebfb82eeaaf5378439c", "baseChecksum": "874fb8d79eb8715b9892cb64fbb77160", "status": "translated" + }, + "ru": { + "checksum": "fa210ccd7b7d9347d63fbc720faeb1bf", + "baseChecksum": "874fb8d79eb8715b9892cb64fbb77160", + "status": "translated" + }, + "ja": { + "checksum": "826da54bd00eb095a391f518f9241381", + "baseChecksum": "874fb8d79eb8715b9892cb64fbb77160", + "status": "translated" + }, + "de": { + "checksum": "f4663967ea5bc4f80db9cdadde1d909e", + "baseChecksum": "874fb8d79eb8715b9892cb64fbb77160", + "status": "translated" } }, "keysCountX": { @@ -42,6 +72,21 @@ "checksum": "2ccecfa93e0d0c95b7f229684871db68", "baseChecksum": "2ccecfa93e0d0c95b7f229684871db68", "status": "new" + }, + "ru": { + "checksum": "2ccecfa93e0d0c95b7f229684871db68", + "baseChecksum": "2ccecfa93e0d0c95b7f229684871db68", + "status": "new" + }, + "ja": { + "checksum": "2ccecfa93e0d0c95b7f229684871db68", + "baseChecksum": "2ccecfa93e0d0c95b7f229684871db68", + "status": "new" + }, + "de": { + "checksum": "2ccecfa93e0d0c95b7f229684871db68", + "baseChecksum": "2ccecfa93e0d0c95b7f229684871db68", + "status": "new" } }, "localesCountX": { @@ -57,6 +102,21 @@ "checksum": "ab692b642031b8646162616db0a399cf", "baseChecksum": "ab692b642031b8646162616db0a399cf", "status": "new" + }, + "ru": { + "checksum": "ab692b642031b8646162616db0a399cf", + "baseChecksum": "ab692b642031b8646162616db0a399cf", + "status": "new" + }, + "ja": { + "checksum": "ab692b642031b8646162616db0a399cf", + "baseChecksum": "ab692b642031b8646162616db0a399cf", + "status": "new" + }, + "de": { + "checksum": "ab692b642031b8646162616db0a399cf", + "baseChecksum": "ab692b642031b8646162616db0a399cf", + "status": "new" } } } diff --git a/apps/tracker/src/i18n/locale/resource_entries.json b/apps/tracker/src/i18n/locale/resource_entries.json index 27648faa..37ad3135 100644 --- a/apps/tracker/src/i18n/locale/resource_entries.json +++ b/apps/tracker/src/i18n/locale/resource_entries.json @@ -4,13 +4,19 @@ "comment": "Aria-label for the locale picker button showing the current language", "tags": ["locale"], "es": "Idioma actual: {language}", - "fr-ca": "Langue actuelle : {language}" + "fr-ca": "Langue actuelle : {language}", + "ru": "Текущий язык: {language}", + "ja": "現在の言語: {language}", + "de": "Aktuelle Sprache: {language}" }, "selectLanguage": { "source": "Select language", "comment": "Aria-label for the locale selection dropdown menu", "tags": ["locale"], "es": "Seleccionar idioma", - "fr-ca": "Choisir la langue" + "fr-ca": "Choisir la langue", + "ru": "Выберите язык", + "ja": "言語を選択してください", + "de": "Sprache auswählen" } } diff --git a/apps/tracker/src/i18n/locale/tracker_meta.json b/apps/tracker/src/i18n/locale/tracker_meta.json index efb1efe8..976756f4 100644 --- a/apps/tracker/src/i18n/locale/tracker_meta.json +++ b/apps/tracker/src/i18n/locale/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "4f2162f0ff303cdc0003e23b2a584b53", "baseChecksum": "9b2dd4a78521838f059925216f4bf4c6", "status": "translated" + }, + "ru": { + "checksum": "6075bee7aeb0bb25c7548bbdb3c6b99a", + "baseChecksum": "9b2dd4a78521838f059925216f4bf4c6", + "status": "translated" + }, + "ja": { + "checksum": "8baa79412a4f36e906f08a8b950e81b2", + "baseChecksum": "9b2dd4a78521838f059925216f4bf4c6", + "status": "translated" + }, + "de": { + "checksum": "1531b52f7fc2fd210e590097c96ad649", + "baseChecksum": "9b2dd4a78521838f059925216f4bf4c6", + "status": "translated" } }, "selectLanguage": { @@ -27,6 +42,21 @@ "checksum": "232df4332952b6a2c6cf987ece661e60", "baseChecksum": "653777801f96237326d65205bc9129e3", "status": "translated" + }, + "ru": { + "checksum": "792386035adece6656d97f676b6a7c87", + "baseChecksum": "653777801f96237326d65205bc9129e3", + "status": "translated" + }, + "ja": { + "checksum": "42627566fb3f3404065a4c81e93afcfa", + "baseChecksum": "653777801f96237326d65205bc9129e3", + "status": "translated" + }, + "de": { + "checksum": "aba191f444ad81aa746460e135b909fe", + "baseChecksum": "653777801f96237326d65205bc9129e3", + "status": "translated" } } } diff --git a/apps/tracker/src/i18n/theme/resource_entries.json b/apps/tracker/src/i18n/theme/resource_entries.json index c35159b4..68e668dc 100644 --- a/apps/tracker/src/i18n/theme/resource_entries.json +++ b/apps/tracker/src/i18n/theme/resource_entries.json @@ -3,24 +3,36 @@ "source": "Light", "comment": "Theme switcher light mode label", "es": "Claro", - "fr-ca": "Clair" + "fr-ca": "Clair", + "ru": "Свет", + "ja": "ライト", + "de": "Licht" }, "dark": { "source": "Dark", "comment": "Theme switcher dark mode label", "es": "Oscuro", - "fr-ca": "Sombre" + "fr-ca": "Sombre", + "ru": "Темный", + "ja": "暗い", + "de": "Dunkel" }, "system": { "source": "System", "comment": "Theme switcher system mode label", "es": "Sistema", - "fr-ca": "Système" + "fr-ca": "Système", + "ru": "Система", + "ja": "システム", + "de": "System" }, "settings": { "source": "Theme settings", "comment": "Aria-label for theme settings button", "es": "Configuración del tema", - "fr-ca": "Paramètres du thème" + "fr-ca": "Paramètres du thème", + "ru": "Настройки темы", + "ja": "テーマ設定", + "de": "Designeinstellungen" } } diff --git a/apps/tracker/src/i18n/theme/tracker_meta.json b/apps/tracker/src/i18n/theme/tracker_meta.json index b4ef4b2b..c1cd3076 100644 --- a/apps/tracker/src/i18n/theme/tracker_meta.json +++ b/apps/tracker/src/i18n/theme/tracker_meta.json @@ -12,6 +12,21 @@ "checksum": "c7e206a03eb924b8cf6f15e8c70f1f07", "baseChecksum": "9914a0ce04a7b7b6a8e39bec55064b82", "status": "new" + }, + "ru": { + "checksum": "64f29ae4503509124973fbba7b822d88", + "baseChecksum": "9914a0ce04a7b7b6a8e39bec55064b82", + "status": "translated" + }, + "ja": { + "checksum": "2174839253a0130780fff656fa933796", + "baseChecksum": "9914a0ce04a7b7b6a8e39bec55064b82", + "status": "translated" + }, + "de": { + "checksum": "c8f1ac1513293af37c9ad8dc06101be6", + "baseChecksum": "9914a0ce04a7b7b6a8e39bec55064b82", + "status": "translated" } }, "dark": { @@ -27,6 +42,21 @@ "checksum": "19bdcdffdcb06cb2f0a62af523ec7fea", "baseChecksum": "a18366b217ebf811ad1886e4f4f865b2", "status": "new" + }, + "ru": { + "checksum": "1d20f24767fa50f6c6846bec0a3b6bad", + "baseChecksum": "a18366b217ebf811ad1886e4f4f865b2", + "status": "translated" + }, + "ja": { + "checksum": "a0256100275b5af922ddf1d8cd054a45", + "baseChecksum": "a18366b217ebf811ad1886e4f4f865b2", + "status": "translated" + }, + "de": { + "checksum": "e8ad273a49203705685b42a379367d2f", + "baseChecksum": "a18366b217ebf811ad1886e4f4f865b2", + "status": "translated" } }, "system": { @@ -42,6 +72,21 @@ "checksum": "b222ce1d25f19d7b8ca005440c794baf", "baseChecksum": "a45da96d0bf6575970f2d27af22be28a", "status": "new" + }, + "ru": { + "checksum": "8d8c85f7294619318a9064c198372b09", + "baseChecksum": "a45da96d0bf6575970f2d27af22be28a", + "status": "translated" + }, + "ja": { + "checksum": "6b46505ad5d38932a5771f1261e21b1a", + "baseChecksum": "a45da96d0bf6575970f2d27af22be28a", + "status": "translated" + }, + "de": { + "checksum": "a45da96d0bf6575970f2d27af22be28a", + "baseChecksum": "a45da96d0bf6575970f2d27af22be28a", + "status": "translated" } }, "settings": { @@ -57,6 +102,21 @@ "checksum": "30aa80ebeaa3348e9dcefee1ac3ae5fe", "baseChecksum": "55b8deb25fdc0f8b628027f7d1d21cbe", "status": "new" + }, + "ru": { + "checksum": "e11e346c34aa99447a5979976e69905e", + "baseChecksum": "55b8deb25fdc0f8b628027f7d1d21cbe", + "status": "translated" + }, + "ja": { + "checksum": "011045e70d825df3367471773c09a58a", + "baseChecksum": "55b8deb25fdc0f8b628027f7d1d21cbe", + "status": "translated" + }, + "de": { + "checksum": "2a3784e0720dd8045567b1d48441e0bb", + "baseChecksum": "55b8deb25fdc0f8b628027f7d1d21cbe", + "status": "translated" } } } diff --git a/docs-site/docusaurus.config.ts b/docs-site/docusaurus.config.ts new file mode 100644 index 00000000..fe5c422f --- /dev/null +++ b/docs-site/docusaurus.config.ts @@ -0,0 +1,98 @@ +import type { Config } from '@docusaurus/types'; +import type * as Preset from '@docusaurus/preset-classic'; + +const config: Config = { + title: 'Lingo Tracker', + tagline: 'Effortlessly Track, Validate, and Manage Your Translations', + favicon: 'img/favicon.png', + + url: 'https://simoncodes-ca.github.io', + baseUrl: '/lingo-tracker/', + + organizationName: 'simoncodes-ca', + projectName: 'lingo-tracker', + trailingSlash: false, + + onBrokenLinks: 'throw', + markdown: { + hooks: { + onBrokenMarkdownLinks: 'warn', + }, + }, + + i18n: { + defaultLocale: 'en', + locales: ['en'], + }, + + presets: [ + [ + 'classic', + { + docs: { + path: '../docs', + routeBasePath: 'docs', + sidebarPath: './sidebars.ts', + editUrl: 'https://github.com/simoncodes-ca/lingo-tracker/edit/develop/', + }, + blog: false, + theme: { + customCss: './src/css/custom.css', + }, + } satisfies Preset.Options, + ], + ], + + themeConfig: { + colorMode: { + defaultMode: 'light', + respectPrefersColorScheme: true, + }, + navbar: { + title: 'Lingo Tracker', + logo: { + alt: 'Lingo Tracker Logo', + src: 'img/logo.png', + srcDark: 'img/logo-dark.png', + }, + items: [ + { + type: 'docSidebar', + sidebarId: 'docsSidebar', + position: 'left', + label: 'Docs', + }, + { + href: 'https://github.com/simoncodes-ca/lingo-tracker', + label: 'GitHub', + position: 'right', + }, + ], + }, + footer: { + style: 'dark', + links: [ + { + title: 'Docs', + items: [ + { label: 'Getting Started', to: '/docs/getting-started' }, + { label: 'CLI Reference', to: '/docs/cli' }, + { label: 'API Reference', to: '/docs/api' }, + ], + }, + { + title: 'Community', + items: [ + { + label: 'GitHub', + href: 'https://github.com/simoncodes-ca/lingo-tracker', + }, + ], + }, + ], + copyright: `Copyright © ${new Date().getFullYear()} SimonCodes. Built with Docusaurus.`, + }, + } satisfies Preset.ThemeConfig, +}; + +export default config; diff --git a/docs-site/package.json b/docs-site/package.json new file mode 100644 index 00000000..b9f0658d --- /dev/null +++ b/docs-site/package.json @@ -0,0 +1,30 @@ +{ + "name": "lingo-tracker-docs", + "version": "0.0.0", + "private": true, + "scripts": { + "start": "docusaurus start", + "build": "docusaurus build", + "serve": "docusaurus serve", + "clear": "docusaurus clear" + }, + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/preset-classic": "3.9.2", + "prism-react-renderer": "^2.3.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "devDependencies": { + "@docusaurus/types": "3.9.2", + "typescript": "~5.9.2" + }, + "engines": { + "node": ">=20" + }, + "pnpm": { + "overrides": { + "webpack": "5.95.0" + } + } +} diff --git a/docs-site/pnpm-lock.yaml b/docs-site/pnpm-lock.yaml new file mode 100644 index 00000000..e2157b2c --- /dev/null +++ b/docs-site/pnpm-lock.yaml @@ -0,0 +1,11670 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +overrides: + webpack: 5.95.0 + +importers: + + .: + dependencies: + '@docusaurus/core': + specifier: 3.9.2 + version: 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/preset-classic': + specifier: 3.9.2 + version: 3.9.2(@algolia/client-search@5.50.1)(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(@types/react@19.2.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.3) + prism-react-renderer: + specifier: ^2.3.0 + version: 2.4.1(react@18.3.1) + react: + specifier: ^18.0.0 + version: 18.3.1 + react-dom: + specifier: ^18.0.0 + version: 18.3.1(react@18.3.1) + devDependencies: + '@docusaurus/types': + specifier: 3.9.2 + version: 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + typescript: + specifier: ~5.9.2 + version: 5.9.3 + +packages: + + '@algolia/abtesting@1.16.1': + resolution: {integrity: sha512-Xxk4l00pYI+jE0PNw8y0MvsQWh5278WRtZQav8/BMMi3HKi2xmeuqe11WJ3y8/6nuBHdv39w76OpJb09TMfAVQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/autocomplete-core@1.19.2': + resolution: {integrity: sha512-mKv7RyuAzXvwmq+0XRK8HqZXt9iZ5Kkm2huLjgn5JoCPtDy+oh9yxUMfDDaVCw0oyzZ1isdJBc7l9nuCyyR7Nw==} + + '@algolia/autocomplete-plugin-algolia-insights@1.19.2': + resolution: {integrity: sha512-TjxbcC/r4vwmnZaPwrHtkXNeqvlpdyR+oR9Wi2XyfORkiGkLTVhX2j+O9SaCCINbKoDfc+c2PB8NjfOnz7+oKg==} + peerDependencies: + search-insights: '>= 1 < 3' + + '@algolia/autocomplete-shared@1.19.2': + resolution: {integrity: sha512-jEazxZTVD2nLrC+wYlVHQgpBoBB5KPStrJxLzsIFl6Kqd1AlG9sIAGl39V5tECLpIQzB3Qa2T6ZPJ1ChkwMK/w==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/client-abtesting@5.50.1': + resolution: {integrity: sha512-4peZlPXMwTOey9q1rQKMdCnwZb/E95/1e+7KujXpLLSh0FawJzg//U2NM+r4AiJy4+naT2MTBhj0K30yshnVTA==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-analytics@5.50.1': + resolution: {integrity: sha512-i+aWHHG8NZvGFHtPeMZkxL2Loc6Fm7iaRo15lYSMx8gFL+at9vgdWxhka7mD1fqxkrxXsQstUBCIsSY8FvkEOw==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-common@5.50.1': + resolution: {integrity: sha512-Hw52Fwapyk/7hMSV/fI4+s3H9MGZEUcRh4VphyXLAk2oLYdndVUkc6KBi0zwHSzwPAr+ZBwFPe2x6naUt9mZGw==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-insights@5.50.1': + resolution: {integrity: sha512-Bn/wtwhJ7p1OD/6pY+Zzn+zlu2N/SJnH46md/PAbvqIzmjVuwjNwD4y0vV5Ov8naeukXdd7UU9v550+v8+mtlg==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-personalization@5.50.1': + resolution: {integrity: sha512-0V4Tu0RWR8YxkgI9EPVOZHGE4K5pEIhkLNN0CTkP/rnPsqaaSQpNMYW3/mGWdiKOWbX0iVmwLB9QESk3H0jS5g==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-query-suggestions@5.50.1': + resolution: {integrity: sha512-jofcWNYMXJDDr87Z2eivlWY6o71Zn7F7aOvQCXSDAo9QTlyf7BhXEsZymLUvF0O1yU9Q9wvrjAWn8uVHYnAvgw==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-search@5.50.1': + resolution: {integrity: sha512-OteRb8WubcmEvU0YlMJwCXs3Q6xrdkb0v50/qZBJP1TF0CvujFZQM++9BjEkTER/Jr9wbPHvjSFKnbMta0b4dQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/events@4.0.1': + resolution: {integrity: sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==} + + '@algolia/ingestion@1.50.1': + resolution: {integrity: sha512-0GmfSgDQK6oiIVXnJvGxtNFOfosBspRTR7csCOYCTL1P8QtxX2vDCIKwTM7xdSAEbJaZ43QlWg25q0Qdsndz8Q==} + engines: {node: '>= 14.0.0'} + + '@algolia/monitoring@1.50.1': + resolution: {integrity: sha512-ySuigKEe4YjYV3si8NVk9BHQpFj/1B+ON7DhhvTvbrZJseHQQloxzq0yHwKmznSdlO6C956fx4pcfOKkZClsyg==} + engines: {node: '>= 14.0.0'} + + '@algolia/recommend@5.50.1': + resolution: {integrity: sha512-Cp8T/B0gVmjFlzzp6eP47hwKh5FGyeqQp1N48/ANDdvdiQkPqLyFHQVDwLBH0LddfIPQE+yqmZIgmKc82haF4A==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-browser-xhr@5.50.1': + resolution: {integrity: sha512-XKdGGLikfrlK66ZSXh/vWcXZZ8Vg3byDFbJD8pwEvN1FoBRGxhxya476IY2ohoTymLa4qB5LBRlIa+2TLHx3Uw==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-fetch@5.50.1': + resolution: {integrity: sha512-mBAU6WyVsDwhHyGM+nodt1/oebHxgvuLlOAoMGbj/1i6LygDHZWDgL1t5JEs37x9Aywv7ZGhqbM1GsfZ54sU6g==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-node-http@5.50.1': + resolution: {integrity: sha512-qmo1LXrNKLHvJE6mdQbLnsZAoZvj7VyF2ft4xmbSGWI2WWm87fx/CjUX4kEExt4y0a6T6nEts6ofpUfH5TEE1A==} + engines: {node: '>= 14.0.0'} + + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.28.6': + resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-create-regexp-features-plugin@7.28.5': + resolution: {integrity: sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-define-polyfill-provider@0.6.8': + resolution: {integrity: sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.28.5': + resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} + engines: {node: '>=6.9.0'} + + '@babel/helper-remap-async-to-generator@7.27.1': + resolution: {integrity: sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-replace-supers@7.28.6': + resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-wrap-function@7.28.6': + resolution: {integrity: sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5': + resolution: {integrity: sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1': + resolution: {integrity: sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1': + resolution: {integrity: sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1': + resolution: {integrity: sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6': + resolution: {integrity: sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-dynamic-import@7.8.3': + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-assertions@7.28.6': + resolution: {integrity: sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.28.6': + resolution: {integrity: sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.28.6': + resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.28.6': + resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6': + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-arrow-functions@7.27.1': + resolution: {integrity: sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-generator-functions@7.29.0': + resolution: {integrity: sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-to-generator@7.28.6': + resolution: {integrity: sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoped-functions@7.27.1': + resolution: {integrity: sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoping@7.28.6': + resolution: {integrity: sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-properties@7.28.6': + resolution: {integrity: sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-static-block@7.28.6': + resolution: {integrity: sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + + '@babel/plugin-transform-classes@7.28.6': + resolution: {integrity: sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-computed-properties@7.28.6': + resolution: {integrity: sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-destructuring@7.28.5': + resolution: {integrity: sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-dotall-regex@7.28.6': + resolution: {integrity: sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-keys@7.27.1': + resolution: {integrity: sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0': + resolution: {integrity: sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-dynamic-import@7.27.1': + resolution: {integrity: sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-explicit-resource-management@7.28.6': + resolution: {integrity: sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-exponentiation-operator@7.28.6': + resolution: {integrity: sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-export-namespace-from@7.27.1': + resolution: {integrity: sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-for-of@7.27.1': + resolution: {integrity: sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-function-name@7.27.1': + resolution: {integrity: sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-json-strings@7.28.6': + resolution: {integrity: sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-literals@7.27.1': + resolution: {integrity: sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-logical-assignment-operators@7.28.6': + resolution: {integrity: sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-member-expression-literals@7.27.1': + resolution: {integrity: sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-amd@7.27.1': + resolution: {integrity: sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.28.6': + resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-systemjs@7.29.0': + resolution: {integrity: sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-umd@7.27.1': + resolution: {integrity: sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0': + resolution: {integrity: sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-new-target@7.27.1': + resolution: {integrity: sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6': + resolution: {integrity: sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-numeric-separator@7.28.6': + resolution: {integrity: sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-rest-spread@7.28.6': + resolution: {integrity: sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-super@7.27.1': + resolution: {integrity: sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-catch-binding@7.28.6': + resolution: {integrity: sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-chaining@7.28.6': + resolution: {integrity: sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-parameters@7.27.7': + resolution: {integrity: sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-methods@7.28.6': + resolution: {integrity: sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-property-in-object@7.28.6': + resolution: {integrity: sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-property-literals@7.27.1': + resolution: {integrity: sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-constant-elements@7.27.1': + resolution: {integrity: sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-display-name@7.28.0': + resolution: {integrity: sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-development@7.27.1': + resolution: {integrity: sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx@7.28.6': + resolution: {integrity: sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-pure-annotations@7.27.1': + resolution: {integrity: sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-regenerator@7.29.0': + resolution: {integrity: sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-regexp-modifiers@7.28.6': + resolution: {integrity: sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-reserved-words@7.27.1': + resolution: {integrity: sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-runtime@7.29.0': + resolution: {integrity: sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-shorthand-properties@7.27.1': + resolution: {integrity: sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-spread@7.28.6': + resolution: {integrity: sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-sticky-regex@7.27.1': + resolution: {integrity: sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-template-literals@7.27.1': + resolution: {integrity: sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typeof-symbol@7.27.1': + resolution: {integrity: sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.28.6': + resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-escapes@7.27.1': + resolution: {integrity: sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-property-regex@7.28.6': + resolution: {integrity: sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-regex@7.27.1': + resolution: {integrity: sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-sets-regex@7.28.6': + resolution: {integrity: sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/preset-env@7.29.2': + resolution: {integrity: sha512-DYD23veRYGvBFhcTY1iUvJnDNpuqNd/BzBwCvzOTKUnJjKg5kpUBh3/u9585Agdkgj+QuygG7jLfOPWMa2KVNw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-modules@0.1.6-no-external-plugins': + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + + '@babel/preset-react@7.28.5': + resolution: {integrity: sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-typescript@7.28.5': + resolution: {integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime-corejs3@7.29.2': + resolution: {integrity: sha512-Lc94FOD5+0aXhdb0Tdg3RUtqT6yWbI/BbFWvlaSJ3gAb9Ks+99nHRDKADVqC37er4eCB0fHyWT+y+K3QOvJKbw==} + engines: {node: '>=6.9.0'} + + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + + '@colors/colors@1.5.0': + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + + '@csstools/cascade-layer-name-parser@2.0.5': + resolution: {integrity: sha512-p1ko5eHgV+MgXFVa4STPKpvPxr6ReS8oS2jzTukjR74i5zJNyWO1ZM1m8YKBXnzDKWfBN1ztLYlHxbVemDD88A==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/color-helpers@5.1.0': + resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} + engines: {node: '>=18'} + + '@csstools/css-calc@2.1.4': + resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-color-parser@3.1.0': + resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-parser-algorithms@3.0.5': + resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-tokenizer@3.0.4': + resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} + engines: {node: '>=18'} + + '@csstools/media-query-list-parser@4.0.3': + resolution: {integrity: sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/postcss-alpha-function@1.0.1': + resolution: {integrity: sha512-isfLLwksH3yHkFXfCI2Gcaqg7wGGHZZwunoJzEZk0yKYIokgre6hYVFibKL3SYAoR1kBXova8LB+JoO5vZzi9w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-cascade-layers@5.0.2': + resolution: {integrity: sha512-nWBE08nhO8uWl6kSAeCx4im7QfVko3zLrtgWZY4/bP87zrSPpSyN/3W3TDqz1jJuH+kbKOHXg5rJnK+ZVYcFFg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-color-function-display-p3-linear@1.0.1': + resolution: {integrity: sha512-E5qusdzhlmO1TztYzDIi8XPdPoYOjoTY6HBYBCYSj+Gn4gQRBlvjgPQXzfzuPQqt8EhkC/SzPKObg4Mbn8/xMg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-color-function@4.0.12': + resolution: {integrity: sha512-yx3cljQKRaSBc2hfh8rMZFZzChaFgwmO2JfFgFr1vMcF3C/uyy5I4RFIBOIWGq1D+XbKCG789CGkG6zzkLpagA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-color-mix-function@3.0.12': + resolution: {integrity: sha512-4STERZfCP5Jcs13P1U5pTvI9SkgLgfMUMhdXW8IlJWkzOOOqhZIjcNhWtNJZes2nkBDsIKJ0CJtFtuaZ00moag==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-color-mix-variadic-function-arguments@1.0.2': + resolution: {integrity: sha512-rM67Gp9lRAkTo+X31DUqMEq+iK+EFqsidfecmhrteErxJZb6tUoJBVQca1Vn1GpDql1s1rD1pKcuYzMsg7Z1KQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-content-alt-text@2.0.8': + resolution: {integrity: sha512-9SfEW9QCxEpTlNMnpSqFaHyzsiRpZ5J5+KqCu1u5/eEJAWsMhzT40qf0FIbeeglEvrGRMdDzAxMIz3wqoGSb+Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-contrast-color-function@2.0.12': + resolution: {integrity: sha512-YbwWckjK3qwKjeYz/CijgcS7WDUCtKTd8ShLztm3/i5dhh4NaqzsbYnhm4bjrpFpnLZ31jVcbK8YL77z3GBPzA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-exponential-functions@2.0.9': + resolution: {integrity: sha512-abg2W/PI3HXwS/CZshSa79kNWNZHdJPMBXeZNyPQFbbj8sKO3jXxOt/wF7juJVjyDTc6JrvaUZYFcSBZBhaxjw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-font-format-keywords@4.0.0': + resolution: {integrity: sha512-usBzw9aCRDvchpok6C+4TXC57btc4bJtmKQWOHQxOVKen1ZfVqBUuCZ/wuqdX5GHsD0NRSr9XTP+5ID1ZZQBXw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-gamut-mapping@2.0.11': + resolution: {integrity: sha512-fCpCUgZNE2piVJKC76zFsgVW1apF6dpYsqGyH8SIeCcM4pTEsRTWTLCaJIMKFEundsCKwY1rwfhtrio04RJ4Dw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-gradients-interpolation-method@5.0.12': + resolution: {integrity: sha512-jugzjwkUY0wtNrZlFeyXzimUL3hN4xMvoPnIXxoZqxDvjZRiSh+itgHcVUWzJ2VwD/VAMEgCLvtaJHX+4Vj3Ow==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-hwb-function@4.0.12': + resolution: {integrity: sha512-mL/+88Z53KrE4JdePYFJAQWFrcADEqsLprExCM04GDNgHIztwFzj0Mbhd/yxMBngq0NIlz58VVxjt5abNs1VhA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-ic-unit@4.0.4': + resolution: {integrity: sha512-yQ4VmossuOAql65sCPppVO1yfb7hDscf4GseF0VCA/DTDaBc0Wtf8MTqVPfjGYlT5+2buokG0Gp7y0atYZpwjg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-initial@2.0.1': + resolution: {integrity: sha512-L1wLVMSAZ4wovznquK0xmC7QSctzO4D0Is590bxpGqhqjboLXYA16dWZpfwImkdOgACdQ9PqXsuRroW6qPlEsg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-is-pseudo-class@5.0.3': + resolution: {integrity: sha512-jS/TY4SpG4gszAtIg7Qnf3AS2pjcUM5SzxpApOrlndMeGhIbaTzWBzzP/IApXoNWEW7OhcjkRT48jnAUIFXhAQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-light-dark-function@2.0.11': + resolution: {integrity: sha512-fNJcKXJdPM3Lyrbmgw2OBbaioU7yuKZtiXClf4sGdQttitijYlZMD5K7HrC/eF83VRWRrYq6OZ0Lx92leV2LFA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-logical-float-and-clear@3.0.0': + resolution: {integrity: sha512-SEmaHMszwakI2rqKRJgE+8rpotFfne1ZS6bZqBoQIicFyV+xT1UF42eORPxJkVJVrH9C0ctUgwMSn3BLOIZldQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-logical-overflow@2.0.0': + resolution: {integrity: sha512-spzR1MInxPuXKEX2csMamshR4LRaSZ3UXVaRGjeQxl70ySxOhMpP2252RAFsg8QyyBXBzuVOOdx1+bVO5bPIzA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-logical-overscroll-behavior@2.0.0': + resolution: {integrity: sha512-e/webMjoGOSYfqLunyzByZj5KKe5oyVg/YSbie99VEaSDE2kimFm0q1f6t/6Jo+VVCQ/jbe2Xy+uX+C4xzWs4w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-logical-resize@3.0.0': + resolution: {integrity: sha512-DFbHQOFW/+I+MY4Ycd/QN6Dg4Hcbb50elIJCfnwkRTCX05G11SwViI5BbBlg9iHRl4ytB7pmY5ieAFk3ws7yyg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-logical-viewport-units@3.0.4': + resolution: {integrity: sha512-q+eHV1haXA4w9xBwZLKjVKAWn3W2CMqmpNpZUk5kRprvSiBEGMgrNH3/sJZ8UA3JgyHaOt3jwT9uFa4wLX4EqQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-media-minmax@2.0.9': + resolution: {integrity: sha512-af9Qw3uS3JhYLnCbqtZ9crTvvkR+0Se+bBqSr7ykAnl9yKhk6895z9rf+2F4dClIDJWxgn0iZZ1PSdkhrbs2ig==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-media-queries-aspect-ratio-number-values@3.0.5': + resolution: {integrity: sha512-zhAe31xaaXOY2Px8IYfoVTB3wglbJUVigGphFLj6exb7cjZRH9A6adyE22XfFK3P2PzwRk0VDeTJmaxpluyrDg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-nested-calc@4.0.0': + resolution: {integrity: sha512-jMYDdqrQQxE7k9+KjstC3NbsmC063n1FTPLCgCRS2/qHUbHM0mNy9pIn4QIiQGs9I/Bg98vMqw7mJXBxa0N88A==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-normalize-display-values@4.0.1': + resolution: {integrity: sha512-TQUGBuRvxdc7TgNSTevYqrL8oItxiwPDixk20qCB5me/W8uF7BPbhRrAvFuhEoywQp/woRsUZ6SJ+sU5idZAIA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-oklab-function@4.0.12': + resolution: {integrity: sha512-HhlSmnE1NKBhXsTnNGjxvhryKtO7tJd1w42DKOGFD6jSHtYOrsJTQDKPMwvOfrzUAk8t7GcpIfRyM7ssqHpFjg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-position-area-property@1.0.0': + resolution: {integrity: sha512-fUP6KR8qV2NuUZV3Cw8itx0Ep90aRjAZxAEzC3vrl6yjFv+pFsQbR18UuQctEKmA72K9O27CoYiKEgXxkqjg8Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-progressive-custom-properties@4.2.1': + resolution: {integrity: sha512-uPiiXf7IEKtUQXsxu6uWtOlRMXd2QWWy5fhxHDnPdXKCQckPP3E34ZgDoZ62r2iT+UOgWsSbM4NvHE5m3mAEdw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-property-rule-prelude-list@1.0.0': + resolution: {integrity: sha512-IxuQjUXq19fobgmSSvUDO7fVwijDJaZMvWQugxfEUxmjBeDCVaDuMpsZ31MsTm5xbnhA+ElDi0+rQ7sQQGisFA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-random-function@2.0.1': + resolution: {integrity: sha512-q+FQaNiRBhnoSNo+GzqGOIBKoHQ43lYz0ICrV+UudfWnEF6ksS6DsBIJSISKQT2Bvu3g4k6r7t0zYrk5pDlo8w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-relative-color-syntax@3.0.12': + resolution: {integrity: sha512-0RLIeONxu/mtxRtf3o41Lq2ghLimw0w9ByLWnnEVuy89exmEEq8bynveBxNW3nyHqLAFEeNtVEmC1QK9MZ8Huw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-scope-pseudo-class@4.0.1': + resolution: {integrity: sha512-IMi9FwtH6LMNuLea1bjVMQAsUhFxJnyLSgOp/cpv5hrzWmrUYU5fm0EguNDIIOHUqzXode8F/1qkC/tEo/qN8Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-sign-functions@1.1.4': + resolution: {integrity: sha512-P97h1XqRPcfcJndFdG95Gv/6ZzxUBBISem0IDqPZ7WMvc/wlO+yU0c5D/OCpZ5TJoTt63Ok3knGk64N+o6L2Pg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-stepped-value-functions@4.0.9': + resolution: {integrity: sha512-h9btycWrsex4dNLeQfyU3y3w40LMQooJWFMm/SK9lrKguHDcFl4VMkncKKoXi2z5rM9YGWbUQABI8BT2UydIcA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-syntax-descriptor-syntax-production@1.0.1': + resolution: {integrity: sha512-GneqQWefjM//f4hJ/Kbox0C6f2T7+pi4/fqTqOFGTL3EjnvOReTqO1qUQ30CaUjkwjYq9qZ41hzarrAxCc4gow==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-system-ui-font-family@1.0.0': + resolution: {integrity: sha512-s3xdBvfWYfoPSBsikDXbuorcMG1nN1M6GdU0qBsGfcmNR0A/qhloQZpTxjA3Xsyrk1VJvwb2pOfiOT3at/DuIQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-text-decoration-shorthand@4.0.3': + resolution: {integrity: sha512-KSkGgZfx0kQjRIYnpsD7X2Om9BUXX/Kii77VBifQW9Ih929hK0KNjVngHDH0bFB9GmfWcR9vJYJJRvw/NQjkrA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-trigonometric-functions@4.0.9': + resolution: {integrity: sha512-Hnh5zJUdpNrJqK9v1/E3BbrQhaDTj5YiX7P61TOvUhoDHnUmsNNxcDAgkQ32RrcWx9GVUvfUNPcUkn8R3vIX6A==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-unset-value@4.0.0': + resolution: {integrity: sha512-cBz3tOCI5Fw6NIFEwU3RiwK6mn3nKegjpJuzCndoGq3BZPkUjnsq7uQmIeMNeMbMk7YD2MfKcgCpZwX5jyXqCA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/selector-resolve-nested@3.1.0': + resolution: {integrity: sha512-mf1LEW0tJLKfWyvn5KdDrhpxHyuxpbNwTIwOYLIvsTffeyOf85j5oIzfG0yosxDgx/sswlqBnESYUcQH0vgZ0g==} + engines: {node: '>=18'} + peerDependencies: + postcss-selector-parser: ^7.0.0 + + '@csstools/selector-specificity@5.0.0': + resolution: {integrity: sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==} + engines: {node: '>=18'} + peerDependencies: + postcss-selector-parser: ^7.0.0 + + '@csstools/utilities@2.0.0': + resolution: {integrity: sha512-5VdOr0Z71u+Yp3ozOx8T11N703wIFGVRgOWbOZMKgglPJsWA54MRIoMNVMa7shUToIhx5J8vX4sOZgD2XiihiQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@discoveryjs/json-ext@0.5.7': + resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} + engines: {node: '>=10.0.0'} + + '@docsearch/core@4.6.2': + resolution: {integrity: sha512-/S0e6Dj7Zcm8m9Rru49YEX49dhU11be68c+S/BCyN8zQsTTgkKzXlhRbVL5mV6lOLC2+ZRRryaTdcm070Ug2oA==} + peerDependencies: + '@types/react': '>= 16.8.0 < 20.0.0' + react: '>= 16.8.0 < 20.0.0' + react-dom: '>= 16.8.0 < 20.0.0' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + react-dom: + optional: true + + '@docsearch/css@4.6.2': + resolution: {integrity: sha512-fH/cn8BjEEdM2nJdjNMHIvOVYupG6AIDtFVDgIZrNzdCSj4KXr9kd+hsehqsNGYjpUjObeKYKvgy/IwCb1jZYQ==} + + '@docsearch/react@4.6.2': + resolution: {integrity: sha512-/BbtGFtqVOGwZx0dw/UfhN/0/DmMQYnulY4iv0tPRhC2JCXv0ka/+izwt3Jzo1ZxXS/2eMvv9zHsBJOK1I9f/w==} + peerDependencies: + '@types/react': '>= 16.8.0 < 20.0.0' + react: '>= 16.8.0 < 20.0.0' + react-dom: '>= 16.8.0 < 20.0.0' + search-insights: '>= 1 < 3' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + react-dom: + optional: true + search-insights: + optional: true + + '@docusaurus/babel@3.9.2': + resolution: {integrity: sha512-GEANdi/SgER+L7Japs25YiGil/AUDnFFHaCGPBbundxoWtCkA2lmy7/tFmgED4y1htAy6Oi4wkJEQdGssnw9MA==} + engines: {node: '>=20.0'} + + '@docusaurus/bundler@3.9.2': + resolution: {integrity: sha512-ZOVi6GYgTcsZcUzjblpzk3wH1Fya2VNpd5jtHoCCFcJlMQ1EYXZetfAnRHLcyiFeBABaI1ltTYbOBtH/gahGVA==} + engines: {node: '>=20.0'} + peerDependencies: + '@docusaurus/faster': '*' + peerDependenciesMeta: + '@docusaurus/faster': + optional: true + + '@docusaurus/core@3.9.2': + resolution: {integrity: sha512-HbjwKeC+pHUFBfLMNzuSjqFE/58+rLVKmOU3lxQrpsxLBOGosYco/Q0GduBb0/jEMRiyEqjNT/01rRdOMWq5pw==} + engines: {node: '>=20.0'} + hasBin: true + peerDependencies: + '@mdx-js/react': ^3.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/cssnano-preset@3.9.2': + resolution: {integrity: sha512-8gBKup94aGttRduABsj7bpPFTX7kbwu+xh3K9NMCF5K4bWBqTFYW+REKHF6iBVDHRJ4grZdIPbvkiHd/XNKRMQ==} + engines: {node: '>=20.0'} + + '@docusaurus/logger@3.9.2': + resolution: {integrity: sha512-/SVCc57ByARzGSU60c50rMyQlBuMIJCjcsJlkphxY6B0GV4UH3tcA1994N8fFfbJ9kX3jIBe/xg3XP5qBtGDbA==} + engines: {node: '>=20.0'} + + '@docusaurus/mdx-loader@3.9.2': + resolution: {integrity: sha512-wiYoGwF9gdd6rev62xDU8AAM8JuLI/hlwOtCzMmYcspEkzecKrP8J8X+KpYnTlACBUUtXNJpSoCwFWJhLRevzQ==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/module-type-aliases@3.9.2': + resolution: {integrity: sha512-8qVe2QA9hVLzvnxP46ysuofJUIc/yYQ82tvA/rBTrnpXtCjNSFLxEZfd5U8cYZuJIVlkPxamsIgwd5tGZXfvew==} + peerDependencies: + react: '*' + react-dom: '*' + + '@docusaurus/plugin-content-blog@3.9.2': + resolution: {integrity: sha512-3I2HXy3L1QcjLJLGAoTvoBnpOwa6DPUa3Q0dMK19UTY9mhPkKQg/DYhAGTiBUKcTR0f08iw7kLPqOhIgdV3eVQ==} + engines: {node: '>=20.0'} + peerDependencies: + '@docusaurus/plugin-content-docs': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-content-docs@3.9.2': + resolution: {integrity: sha512-C5wZsGuKTY8jEYsqdxhhFOe1ZDjH0uIYJ9T/jebHwkyxqnr4wW0jTkB72OMqNjsoQRcb0JN3PcSeTwFlVgzCZg==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-content-pages@3.9.2': + resolution: {integrity: sha512-s4849w/p4noXUrGpPUF0BPqIAfdAe76BLaRGAGKZ1gTDNiGxGcpsLcwJ9OTi1/V8A+AzvsmI9pkjie2zjIQZKA==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-css-cascade-layers@3.9.2': + resolution: {integrity: sha512-w1s3+Ss+eOQbscGM4cfIFBlVg/QKxyYgj26k5AnakuHkKxH6004ZtuLe5awMBotIYF2bbGDoDhpgQ4r/kcj4rQ==} + engines: {node: '>=20.0'} + + '@docusaurus/plugin-debug@3.9.2': + resolution: {integrity: sha512-j7a5hWuAFxyQAkilZwhsQ/b3T7FfHZ+0dub6j/GxKNFJp2h9qk/P1Bp7vrGASnvA9KNQBBL1ZXTe7jlh4VdPdA==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-google-analytics@3.9.2': + resolution: {integrity: sha512-mAwwQJ1Us9jL/lVjXtErXto4p4/iaLlweC54yDUK1a97WfkC6Z2k5/769JsFgwOwOP+n5mUQGACXOEQ0XDuVUw==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-google-gtag@3.9.2': + resolution: {integrity: sha512-YJ4lDCphabBtw19ooSlc1MnxtYGpjFV9rEdzjLsUnBCeis2djUyCozZaFhCg6NGEwOn7HDDyMh0yzcdRpnuIvA==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-google-tag-manager@3.9.2': + resolution: {integrity: sha512-LJtIrkZN/tuHD8NqDAW1Tnw0ekOwRTfobWPsdO15YxcicBo2ykKF0/D6n0vVBfd3srwr9Z6rzrIWYrMzBGrvNw==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-sitemap@3.9.2': + resolution: {integrity: sha512-WLh7ymgDXjG8oPoM/T4/zUP7KcSuFYRZAUTl8vR6VzYkfc18GBM4xLhcT+AKOwun6kBivYKUJf+vlqYJkm+RHw==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-svgr@3.9.2': + resolution: {integrity: sha512-n+1DE+5b3Lnf27TgVU5jM1d4x5tUh2oW5LTsBxJX4PsAPV0JGcmI6p3yLYtEY0LRVEIJh+8RsdQmRE66wSV8mw==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/preset-classic@3.9.2': + resolution: {integrity: sha512-IgyYO2Gvaigi21LuDIe+nvmN/dfGXAiMcV/murFqcpjnZc7jxFAxW+9LEjdPt61uZLxG4ByW/oUmX/DDK9t/8w==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/react-loadable@6.0.0': + resolution: {integrity: sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==} + peerDependencies: + react: '*' + + '@docusaurus/theme-classic@3.9.2': + resolution: {integrity: sha512-IGUsArG5hhekXd7RDb11v94ycpJpFdJPkLnt10fFQWOVxAtq5/D7hT6lzc2fhyQKaaCE62qVajOMKL7OiAFAIA==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/theme-common@3.9.2': + resolution: {integrity: sha512-6c4DAbR6n6nPbnZhY2V3tzpnKnGL+6aOsLvFL26VRqhlczli9eWG0VDUNoCQEPnGwDMhPS42UhSAnz5pThm5Ag==} + engines: {node: '>=20.0'} + peerDependencies: + '@docusaurus/plugin-content-docs': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/theme-search-algolia@3.9.2': + resolution: {integrity: sha512-GBDSFNwjnh5/LdkxCKQHkgO2pIMX1447BxYUBG2wBiajS21uj64a+gH/qlbQjDLxmGrbrllBrtJkUHxIsiwRnw==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/theme-translations@3.9.2': + resolution: {integrity: sha512-vIryvpP18ON9T9rjgMRFLr2xJVDpw1rtagEGf8Ccce4CkTrvM/fRB8N2nyWYOW5u3DdjkwKw5fBa+3tbn9P4PA==} + engines: {node: '>=20.0'} + + '@docusaurus/types@3.9.2': + resolution: {integrity: sha512-Ux1JUNswg+EfUEmajJjyhIohKceitY/yzjRUpu04WXgvVz+fbhVC0p+R0JhvEu4ytw8zIAys2hrdpQPBHRIa8Q==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/utils-common@3.9.2': + resolution: {integrity: sha512-I53UC1QctruA6SWLvbjbhCpAw7+X7PePoe5pYcwTOEXD/PxeP8LnECAhTHHwWCblyUX5bMi4QLRkxvyZ+IT8Aw==} + engines: {node: '>=20.0'} + + '@docusaurus/utils-validation@3.9.2': + resolution: {integrity: sha512-l7yk3X5VnNmATbwijJkexdhulNsQaNDwoagiwujXoxFbWLcxHQqNQ+c/IAlzrfMMOfa/8xSBZ7KEKDesE/2J7A==} + engines: {node: '>=20.0'} + + '@docusaurus/utils@3.9.2': + resolution: {integrity: sha512-lBSBiRruFurFKXr5Hbsl2thmGweAPmddhF3jb99U4EMDA5L+e5Y1rAkOS07Nvrup7HUMBDrCV45meaxZnt28nQ==} + engines: {node: '>=20.0'} + + '@hapi/hoek@9.3.0': + resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} + + '@hapi/topo@5.1.0': + resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.11': + resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@jsonjoy.com/base64@1.1.2': + resolution: {integrity: sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/base64@17.67.0': + resolution: {integrity: sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/buffers@1.2.1': + resolution: {integrity: sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/buffers@17.67.0': + resolution: {integrity: sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/codegen@1.0.0': + resolution: {integrity: sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/codegen@17.67.0': + resolution: {integrity: sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-core@4.57.1': + resolution: {integrity: sha512-YrEi/ZPmgc+GfdO0esBF04qv8boK9Dg9WpRQw/+vM8Qt3nnVIJWIa8HwZ/LXVZ0DB11XUROM8El/7yYTJX+WtA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-fsa@4.57.1': + resolution: {integrity: sha512-ooEPvSW/HQDivPDPZMibHGKZf/QS4WRir1czGZmXmp3MsQqLECZEpN0JobrD8iV9BzsuwdIv+PxtWX9WpPLsIA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-node-builtins@4.57.1': + resolution: {integrity: sha512-XHkFKQ5GSH3uxm8c3ZYXVrexGdscpWKIcMWKFQpMpMJc8gA3AwOMBJXJlgpdJqmrhPyQXxaY9nbkNeYpacC0Og==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-node-to-fsa@4.57.1': + resolution: {integrity: sha512-pqGHyWWzNck4jRfaGV39hkqpY5QjRUQ/nRbNT7FYbBa0xf4bDG+TE1Gt2KWZrSkrkZZDE3qZUjYMbjwSliX6pg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-node-utils@4.57.1': + resolution: {integrity: sha512-vp+7ZzIB8v43G+GLXTS4oDUSQmhAsRz532QmmWBbdYA20s465JvwhkSFvX9cVTqRRAQg+vZ7zWDaIEh0lFe2gw==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-node@4.57.1': + resolution: {integrity: sha512-3YaKhP8gXEKN+2O49GLNfNb5l2gbnCFHyAaybbA2JkkbQP3dpdef7WcUaHAulg/c5Dg4VncHsA3NWAUSZMR5KQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-print@4.57.1': + resolution: {integrity: sha512-Ynct7ZJmfk6qoXDOKfpovNA36ITUx8rChLmRQtW08J73VOiuNsU8PB6d/Xs7fxJC2ohWR3a5AqyjmLojfrw5yw==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-snapshot@4.57.1': + resolution: {integrity: sha512-/oG8xBNFMbDXTq9J7vepSA1kerS5vpgd3p5QZSPd+nX59uwodGJftI51gDYyHRpP57P3WCQf7LHtBYPqwUg2Bg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pack@1.21.0': + resolution: {integrity: sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pack@17.67.0': + resolution: {integrity: sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pointer@1.0.2': + resolution: {integrity: sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pointer@17.67.0': + resolution: {integrity: sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/util@1.9.0': + resolution: {integrity: sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/util@17.67.0': + resolution: {integrity: sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@leichtgewicht/ip-codec@2.0.5': + resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} + + '@mdx-js/mdx@3.1.1': + resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} + + '@mdx-js/react@3.1.1': + resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==} + peerDependencies: + '@types/react': '>=16' + react: '>=16' + + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@peculiar/asn1-cms@2.6.1': + resolution: {integrity: sha512-vdG4fBF6Lkirkcl53q6eOdn3XYKt+kJTG59edgRZORlg/3atWWEReRCx5rYE1ZzTTX6vLK5zDMjHh7vbrcXGtw==} + + '@peculiar/asn1-csr@2.6.1': + resolution: {integrity: sha512-WRWnKfIocHyzFYQTka8O/tXCiBquAPSrRjXbOkHbO4qdmS6loffCEGs+rby6WxxGdJCuunnhS2duHURhjyio6w==} + + '@peculiar/asn1-ecc@2.6.1': + resolution: {integrity: sha512-+Vqw8WFxrtDIN5ehUdvlN2m73exS2JVG0UAyfVB31gIfor3zWEAQPD+K9ydCxaj3MLen9k0JhKpu9LqviuCE1g==} + + '@peculiar/asn1-pfx@2.6.1': + resolution: {integrity: sha512-nB5jVQy3MAAWvq0KY0R2JUZG8bO/bTLpnwyOzXyEh/e54ynGTatAR+csOnXkkVD9AFZ2uL8Z7EV918+qB1qDvw==} + + '@peculiar/asn1-pkcs8@2.6.1': + resolution: {integrity: sha512-JB5iQ9Izn5yGMw3ZG4Nw3Xn/hb/G38GYF3lf7WmJb8JZUydhVGEjK/ZlFSWhnlB7K/4oqEs8HnfFIKklhR58Tw==} + + '@peculiar/asn1-pkcs9@2.6.1': + resolution: {integrity: sha512-5EV8nZoMSxeWmcxWmmcolg22ojZRgJg+Y9MX2fnE2bGRo5KQLqV5IL9kdSQDZxlHz95tHvIq9F//bvL1OeNILw==} + + '@peculiar/asn1-rsa@2.6.1': + resolution: {integrity: sha512-1nVMEh46SElUt5CB3RUTV4EG/z7iYc7EoaDY5ECwganibQPkZ/Y2eMsTKB/LeyrUJ+W/tKoD9WUqIy8vB+CEdA==} + + '@peculiar/asn1-schema@2.6.0': + resolution: {integrity: sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg==} + + '@peculiar/asn1-x509-attr@2.6.1': + resolution: {integrity: sha512-tlW6cxoHwgcQghnJwv3YS+9OO1737zgPogZ+CgWRUK4roEwIPzRH4JEiG770xe5HX2ATfCpmX60gurfWIF9dcQ==} + + '@peculiar/asn1-x509@2.6.1': + resolution: {integrity: sha512-O9jT5F1A2+t3r7C4VT7LYGXqkGLK7Kj1xFpz7U0isPrubwU5PbDoyYtx6MiGst29yq7pXN5vZbQFKRCP+lLZlA==} + + '@peculiar/x509@1.14.3': + resolution: {integrity: sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==} + engines: {node: '>=20.0.0'} + + '@pnpm/config.env-replace@1.1.0': + resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} + engines: {node: '>=12.22.0'} + + '@pnpm/network.ca-file@1.0.2': + resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} + engines: {node: '>=12.22.0'} + + '@pnpm/npm-conf@3.0.2': + resolution: {integrity: sha512-h104Kh26rR8tm+a3Qkc5S4VLYint3FE48as7+/5oCEcKR2idC/pF1G6AhIXKI+eHPJa/3J9i5z0Al47IeGHPkA==} + engines: {node: '>=12'} + + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + + '@sideway/address@4.1.5': + resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} + + '@sideway/formula@3.0.1': + resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==} + + '@sideway/pinpoint@2.0.0': + resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} + + '@sinclair/typebox@0.27.10': + resolution: {integrity: sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==} + + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + + '@sindresorhus/is@5.6.0': + resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} + engines: {node: '>=14.16'} + + '@slorber/react-helmet-async@1.3.0': + resolution: {integrity: sha512-e9/OK8VhwUSc67diWI8Rb3I0YgI9/SBQtnhe9aEuK6MhZm7ntZZimXgwXnd8W96YTmSOb9M4d8LwhRZyhWr/1A==} + peerDependencies: + react: ^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@slorber/remark-comment@1.0.0': + resolution: {integrity: sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==} + + '@svgr/babel-plugin-add-jsx-attribute@8.0.0': + resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0': + resolution: {integrity: sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0': + resolution: {integrity: sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0': + resolution: {integrity: sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-svg-dynamic-title@8.0.0': + resolution: {integrity: sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-svg-em-dimensions@8.0.0': + resolution: {integrity: sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-transform-react-native-svg@8.1.0': + resolution: {integrity: sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-transform-svg-component@8.0.0': + resolution: {integrity: sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==} + engines: {node: '>=12'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-preset@8.1.0': + resolution: {integrity: sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/core@8.1.0': + resolution: {integrity: sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==} + engines: {node: '>=14'} + + '@svgr/hast-util-to-babel-ast@8.0.0': + resolution: {integrity: sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==} + engines: {node: '>=14'} + + '@svgr/plugin-jsx@8.1.0': + resolution: {integrity: sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==} + engines: {node: '>=14'} + peerDependencies: + '@svgr/core': '*' + + '@svgr/plugin-svgo@8.1.0': + resolution: {integrity: sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==} + engines: {node: '>=14'} + peerDependencies: + '@svgr/core': '*' + + '@svgr/webpack@8.1.0': + resolution: {integrity: sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==} + engines: {node: '>=14'} + + '@szmarczak/http-timer@5.0.1': + resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} + engines: {node: '>=14.16'} + + '@types/body-parser@1.19.6': + resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} + + '@types/bonjour@3.5.13': + resolution: {integrity: sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==} + + '@types/connect-history-api-fallback@1.5.4': + resolution: {integrity: sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + + '@types/eslint-scope@3.7.7': + resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} + + '@types/eslint@9.6.1': + resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} + + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/express-serve-static-core@4.19.8': + resolution: {integrity: sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==} + + '@types/express@4.17.25': + resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} + + '@types/gtag.js@0.0.12': + resolution: {integrity: sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/history@4.7.11': + resolution: {integrity: sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==} + + '@types/html-minifier-terser@6.1.0': + resolution: {integrity: sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==} + + '@types/http-cache-semantics@4.2.0': + resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} + + '@types/http-errors@2.0.5': + resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} + + '@types/http-proxy@1.17.17': + resolution: {integrity: sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==} + + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/node@17.0.45': + resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} + + '@types/node@25.6.0': + resolution: {integrity: sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==} + + '@types/prismjs@1.26.6': + resolution: {integrity: sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw==} + + '@types/qs@6.15.0': + resolution: {integrity: sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + + '@types/react-router-config@5.0.11': + resolution: {integrity: sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==} + + '@types/react-router-dom@5.3.3': + resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==} + + '@types/react-router@5.1.20': + resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==} + + '@types/react@19.2.14': + resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + + '@types/retry@0.12.2': + resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==} + + '@types/sax@1.2.7': + resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} + + '@types/send@0.17.6': + resolution: {integrity: sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==} + + '@types/send@1.2.1': + resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} + + '@types/serve-index@1.9.4': + resolution: {integrity: sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==} + + '@types/serve-static@1.15.10': + resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} + + '@types/sockjs@0.3.36': + resolution: {integrity: sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.35': + resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} + + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + '@webassemblyjs/ast@1.14.1': + resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} + + '@webassemblyjs/floating-point-hex-parser@1.13.2': + resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} + + '@webassemblyjs/helper-api-error@1.13.2': + resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} + + '@webassemblyjs/helper-buffer@1.14.1': + resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} + + '@webassemblyjs/helper-numbers@1.13.2': + resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': + resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} + + '@webassemblyjs/helper-wasm-section@1.14.1': + resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} + + '@webassemblyjs/ieee754@1.13.2': + resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} + + '@webassemblyjs/leb128@1.13.2': + resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} + + '@webassemblyjs/utf8@1.13.2': + resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} + + '@webassemblyjs/wasm-edit@1.14.1': + resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} + + '@webassemblyjs/wasm-gen@1.14.1': + resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} + + '@webassemblyjs/wasm-opt@1.14.1': + resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} + + '@webassemblyjs/wasm-parser@1.14.1': + resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} + + '@webassemblyjs/wast-printer@1.14.1': + resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} + + '@xtuc/ieee754@1.2.0': + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + + '@xtuc/long@4.2.2': + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + acorn-import-attributes@1.9.5: + resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} + peerDependencies: + acorn: ^8 + + acorn-import-phases@1.0.4: + resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==} + engines: {node: '>=10.13.0'} + peerDependencies: + acorn: ^8.14.0 + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.3.5: + resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} + engines: {node: '>=0.4.0'} + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + address@1.2.2: + resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} + engines: {node: '>= 10.0.0'} + + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-keywords@3.5.2: + resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} + peerDependencies: + ajv: ^6.9.1 + + ajv-keywords@5.1.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + + ajv@6.14.0: + resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} + + ajv@8.18.0: + resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} + + algoliasearch-helper@3.28.1: + resolution: {integrity: sha512-6iXpbkkrAI5HFpCWXlNmIDSBuoN/U1XnEvb2yJAoWfqrZ+DrybI7MQ5P5mthFaprmocq+zbi6HxnR28xnZAYBw==} + peerDependencies: + algoliasearch: '>= 3.1 < 6' + + algoliasearch@5.50.1: + resolution: {integrity: sha512-/bwdue1/8LWELn/DBalGRfuLsXBLXULJo/yOeavJtDu8rBwxIzC6/Rz9Jg19S21VkJvRuZO1k8CZXBMS73mYbA==} + engines: {node: '>= 14.0.0'} + + ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-html-community@0.0.8: + resolution: {integrity: sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==} + engines: {'0': node >= 0.8.0} + hasBin: true + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + asn1js@3.0.7: + resolution: {integrity: sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ==} + engines: {node: '>=12.0.0'} + + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + + autoprefixer@10.4.27: + resolution: {integrity: sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + + babel-loader@9.2.1: + resolution: {integrity: sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==} + engines: {node: '>= 14.15.0'} + peerDependencies: + '@babel/core': ^7.12.0 + webpack: 5.95.0 + + babel-plugin-dynamic-import-node@2.3.3: + resolution: {integrity: sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==} + + babel-plugin-polyfill-corejs2@0.4.17: + resolution: {integrity: sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-corejs3@0.13.0: + resolution: {integrity: sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-corejs3@0.14.2: + resolution: {integrity: sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-regenerator@0.6.8: + resolution: {integrity: sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + baseline-browser-mapping@2.10.18: + resolution: {integrity: sha512-VSnGQAOLtP5mib/DPyg2/t+Tlv65NTBz83BJBJvmLVHHuKJVaDOBvJJykiT5TR++em5nfAySPccDZDa4oSrn8A==} + engines: {node: '>=6.0.0'} + hasBin: true + + batch@0.6.1: + resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} + + big.js@5.2.2: + resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + body-parser@1.20.4: + resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + bonjour-service@1.3.0: + resolution: {integrity: sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + boxen@6.2.1: + resolution: {integrity: sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + boxen@7.1.1: + resolution: {integrity: sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==} + engines: {node: '>=14.16'} + + brace-expansion@1.1.14: + resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + + bytes@3.0.0: + resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} + engines: {node: '>= 0.8'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + bytestreamjs@2.0.1: + resolution: {integrity: sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==} + engines: {node: '>=6.0.0'} + + cacheable-lookup@7.0.0: + resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} + engines: {node: '>=14.16'} + + cacheable-request@10.2.14: + resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} + engines: {node: '>=14.16'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.9: + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camel-case@4.1.2: + resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + camelcase@7.0.1: + resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} + engines: {node: '>=14.16'} + + caniuse-api@3.0.0: + resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} + + caniuse-lite@1.0.30001787: + resolution: {integrity: sha512-mNcrMN9KeI68u7muanUpEejSLghOKlVhRqS/Za2IeyGllJ9I9otGpR9g3nsw7n4W378TE/LyIteA0+/FOZm4Kg==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.0.0-rc.12: + resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} + engines: {node: '>= 6'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + clean-css@5.3.3: + resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} + engines: {node: '>= 10.0'} + + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + + cli-boxes@3.0.0: + resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} + engines: {node: '>=10'} + + cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} + engines: {node: 10.* || >= 12.*} + + clone-deep@4.0.1: + resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} + engines: {node: '>=6'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colord@2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + combine-promises@1.2.0: + resolution: {integrity: sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==} + engines: {node: '>=10'} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + commander@5.1.0: + resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} + engines: {node: '>= 6'} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + common-path-prefix@3.0.0: + resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} + + compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + + compression@1.8.1: + resolution: {integrity: sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==} + engines: {node: '>= 0.8.0'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + + configstore@6.0.0: + resolution: {integrity: sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==} + engines: {node: '>=12'} + + connect-history-api-fallback@2.0.0: + resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} + engines: {node: '>=0.8'} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + content-disposition@0.5.2: + resolution: {integrity: sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==} + engines: {node: '>= 0.6'} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-signature@1.0.7: + resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + copy-webpack-plugin@11.0.0: + resolution: {integrity: sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==} + engines: {node: '>= 14.15.0'} + peerDependencies: + webpack: 5.95.0 + + core-js-compat@3.49.0: + resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} + + core-js-pure@3.49.0: + resolution: {integrity: sha512-XM4RFka59xATyJv/cS3O3Kml72hQXUeGRuuTmMYFxwzc9/7C8OYTaIR/Ji+Yt8DXzsFLNhat15cE/JP15HrCgw==} + + core-js@3.49.0: + resolution: {integrity: sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cosmiconfig@8.3.6: + resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + crypto-random-string@4.0.0: + resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} + engines: {node: '>=12'} + + css-blank-pseudo@7.0.1: + resolution: {integrity: sha512-jf+twWGDf6LDoXDUode+nc7ZlrqfaNphrBIBrcmeP3D8yw1uPaix1gCC8LUQUGQ6CycuK2opkbFFWFuq/a94ag==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + css-declaration-sorter@7.4.0: + resolution: {integrity: sha512-LTuzjPoyA2vMGKKcaOqKSp7Ub2eGrNfKiZH4LpezxpNrsICGCSFvsQOI29psISxNZtaXibkC2CXzrQ5enMeGGw==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.0.9 + + css-has-pseudo@7.0.3: + resolution: {integrity: sha512-oG+vKuGyqe/xvEMoxAQrhi7uY16deJR3i7wwhBerVrGQKSqUC5GiOVxTpM9F9B9hw0J+eKeOWLH7E9gZ1Dr5rA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + css-loader@6.11.0: + resolution: {integrity: sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==} + engines: {node: '>= 12.13.0'} + peerDependencies: + '@rspack/core': 0.x || 1.x + webpack: 5.95.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + webpack: + optional: true + + css-minimizer-webpack-plugin@5.0.1: + resolution: {integrity: sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==} + engines: {node: '>= 14.15.0'} + peerDependencies: + '@parcel/css': '*' + '@swc/css': '*' + clean-css: '*' + csso: '*' + esbuild: '*' + lightningcss: '*' + webpack: 5.95.0 + peerDependenciesMeta: + '@parcel/css': + optional: true + '@swc/css': + optional: true + clean-css: + optional: true + csso: + optional: true + esbuild: + optional: true + lightningcss: + optional: true + + css-prefers-color-scheme@10.0.0: + resolution: {integrity: sha512-VCtXZAWivRglTZditUfB4StnsWr6YVZ2PRtuxQLKTNRdtAf8tpzaVPE9zXIF3VaSc7O70iK/j1+NXxyQCqdPjQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + css-select@4.3.0: + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} + + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + + cssdb@8.8.0: + resolution: {integrity: sha512-QbLeyz2Bgso1iRlh7IpWk6OKa3lLNGXsujVjDMPl9rOZpxKeiG69icLpbLCFxeURwmcdIfZqQyhlooKJYM4f8Q==} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + cssnano-preset-advanced@6.1.2: + resolution: {integrity: sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + cssnano-preset-default@6.1.2: + resolution: {integrity: sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + cssnano-utils@4.0.2: + resolution: {integrity: sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + cssnano@6.1.2: + resolution: {integrity: sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + debounce@1.2.1: + resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} + engines: {node: '>=18'} + + default-browser@5.5.0: + resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} + engines: {node: '>=18'} + + defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + depd@1.1.2: + resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} + engines: {node: '>= 0.6'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + detect-node@2.1.0: + resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} + + detect-port@1.6.1: + resolution: {integrity: sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==} + engines: {node: '>= 4.0.0'} + hasBin: true + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dns-packet@5.6.1: + resolution: {integrity: sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==} + engines: {node: '>=6'} + + dom-converter@0.2.0: + resolution: {integrity: sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==} + + dom-serializer@1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} + engines: {node: '>= 4'} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + + dot-prop@6.0.1: + resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==} + engines: {node: '>=10'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + electron-to-chromium@1.5.335: + resolution: {integrity: sha512-q9n5T4BR4Xwa2cwbrwcsDJtHD/enpQ5S1xF1IAtdqf5AAgqDFmR/aakqH3ChFdqd/QXJhS3rnnXFtexU7rax6Q==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + emojilib@2.4.0: + resolution: {integrity: sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==} + + emojis-list@3.0.0: + resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} + engines: {node: '>= 4'} + + emoticon@4.1.0: + resolution: {integrity: sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ==} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + enhanced-resolve@5.20.1: + resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} + engines: {node: '>=10.13.0'} + + entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + es-module-lexer@2.0.0: + resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-goat@4.0.0: + resolution: {integrity: sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==} + engines: {node: '>=12'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + + estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + + estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + + estree-util-value-to-estree@3.5.0: + resolution: {integrity: sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ==} + + estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + eta@2.2.0: + resolution: {integrity: sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==} + engines: {node: '>=6.0.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + eval@0.1.8: + resolution: {integrity: sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==} + engines: {node: '>= 0.8'} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + express@4.22.1: + resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==} + engines: {node: '>= 0.10.0'} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fault@2.0.1: + resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} + + faye-websocket@0.11.4: + resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} + engines: {node: '>=0.8.0'} + + feed@4.2.2: + resolution: {integrity: sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==} + engines: {node: '>=0.4.0'} + + figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + + file-loader@6.2.0: + resolution: {integrity: sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: 5.95.0 + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + finalhandler@1.3.2: + resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} + engines: {node: '>= 0.8'} + + find-cache-dir@4.0.0: + resolution: {integrity: sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==} + engines: {node: '>=14.16'} + + find-up@6.3.0: + resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data-encoder@2.1.4: + resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} + engines: {node: '>= 14.17'} + + format@0.2.2: + resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} + engines: {node: '>=0.4.x'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fraction.js@5.3.4: + resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + fs-extra@11.3.4: + resolution: {integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==} + engines: {node: '>=14.14'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-own-enumerable-property-symbols@3.0.2: + resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + github-slugger@1.5.0: + resolution: {integrity: sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob-to-regex.js@1.2.0: + resolution: {integrity: sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + + global-dirs@3.0.1: + resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} + engines: {node: '>=10'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + globby@13.2.2: + resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + got@12.6.1: + resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==} + engines: {node: '>=14.16'} + + graceful-fs@4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + gray-matter@4.0.3: + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} + + gzip-size@6.0.0: + resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} + engines: {node: '>=10'} + + handle-thing@2.0.1: + resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-yarn@3.0.0: + resolution: {integrity: sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hast-util-from-parse5@8.0.3: + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + + hast-util-raw@9.1.0: + resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} + + hast-util-to-estree@3.1.3: + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} + + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-to-parse5@8.0.1: + resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hastscript@9.0.1: + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + history@4.10.1: + resolution: {integrity: sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==} + + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + + hpack.js@2.1.6: + resolution: {integrity: sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + html-minifier-terser@6.1.0: + resolution: {integrity: sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==} + engines: {node: '>=12'} + hasBin: true + + html-minifier-terser@7.2.0: + resolution: {integrity: sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==} + engines: {node: ^14.13.1 || >=16.0.0} + hasBin: true + + html-tags@3.3.1: + resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} + engines: {node: '>=8'} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + html-webpack-plugin@5.6.6: + resolution: {integrity: sha512-bLjW01UTrvoWTJQL5LsMRo1SypHW80FTm12OJRSnr3v6YHNhfe+1r0MYUZJMACxnCHURVnBWRwAsWs2yPU9Ezw==} + engines: {node: '>=10.13.0'} + peerDependencies: + '@rspack/core': 0.x || 1.x + webpack: 5.95.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + webpack: + optional: true + + htmlparser2@6.1.0: + resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==} + + htmlparser2@8.0.2: + resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + + http-deceiver@1.2.7: + resolution: {integrity: sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==} + + http-errors@1.8.1: + resolution: {integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==} + engines: {node: '>= 0.6'} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + http-parser-js@0.5.10: + resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==} + + http-proxy-middleware@2.0.9: + resolution: {integrity: sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/express': ^4.17.13 + peerDependenciesMeta: + '@types/express': + optional: true + + http-proxy@1.18.1: + resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} + engines: {node: '>=8.0.0'} + + http2-wrapper@2.2.1: + resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} + engines: {node: '>=10.19.0'} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + hyperdyperid@1.2.0: + resolution: {integrity: sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==} + engines: {node: '>=10.18'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + icss-utils@5.1.0: + resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + image-size@2.0.2: + resolution: {integrity: sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==} + engines: {node: '>=16.x'} + hasBin: true + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + import-lazy@4.0.0: + resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} + engines: {node: '>=8'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + infima@0.2.0-alpha.45: + resolution: {integrity: sha512-uyH0zfr1erU1OohLk0fT4Rrb94AOhguWNOcD9uGrSpRvNB+6gZXUoJX5J0NtvzBO10YZ9PgvA4NFgt+fYg8ojw==} + engines: {node: '>=12'} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@2.0.0: + resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} + engines: {node: '>=10'} + + inline-style-parser@0.2.7: + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + + invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + ipaddr.js@2.3.0: + resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==} + engines: {node: '>= 10'} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-ci@3.0.1: + resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} + hasBin: true + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-installed-globally@0.4.0: + resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} + engines: {node: '>=10'} + + is-network-error@1.3.1: + resolution: {integrity: sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==} + engines: {node: '>=16'} + + is-npm@6.1.0: + resolution: {integrity: sha512-O2z4/kNgyjhQwVR1Wpkbfc19JIhggF97NZNCpWTnjH7kVcZMUrnut9XSN7txI7VdyIYk5ZatOq3zvSuWpU8hoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-obj@1.0.1: + resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} + engines: {node: '>=0.10.0'} + + is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-plain-obj@3.0.0: + resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==} + engines: {node: '>=10'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + + is-regexp@1.0.0: + resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==} + engines: {node: '>=0.10.0'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} + engines: {node: '>=16'} + + is-yarn-global@0.4.1: + resolution: {integrity: sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==} + engines: {node: '>=12'} + + isarray@0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + + joi@17.13.3: + resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + latest-version@7.0.0: + resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==} + engines: {node: '>=14.16'} + + launch-editor@2.13.2: + resolution: {integrity: sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==} + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + loader-runner@4.3.1: + resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} + engines: {node: '>=6.11.5'} + + loader-utils@2.0.4: + resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==} + engines: {node: '>=8.9.0'} + + locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + + lowercase-keys@3.0.0: + resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} + + markdown-table@2.0.0: + resolution: {integrity: sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdast-util-directive@3.1.0: + resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==} + + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.3: + resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} + + mdast-util-frontmatter@2.0.1: + resolution: {integrity: sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + + mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + memfs@4.57.1: + resolution: {integrity: sha512-WvzrWPwMQT+PtbX2Et64R4qXKK0fj/8pO85MrUCzymX3twwCiJCdvntW3HdhG1teLJcHDDLIKx5+c3HckWYZtQ==} + peerDependencies: + tslib: '2' + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-directive@3.0.2: + resolution: {integrity: sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==} + + micromark-extension-frontmatter@2.0.0: + resolution: {integrity: sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + + micromark-extension-mdx-jsx@3.0.2: + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} + + micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + + micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + + micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + + micromark-factory-space@1.1.0: + resolution: {integrity: sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@1.2.0: + resolution: {integrity: sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@1.1.0: + resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@1.1.0: + resolution: {integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.33.0: + resolution: {integrity: sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==} + engines: {node: '>= 0.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.18: + resolution: {integrity: sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + mimic-response@4.0.0: + resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + mini-css-extract-plugin@2.10.2: + resolution: {integrity: sha512-AOSS0IdEB95ayVkxn5oGzNQwqAi2J0Jb/kKm43t7H73s8+f5873g0yuj0PNvK4dO75mu5DHg4nlgp4k6Kga8eg==} + engines: {node: '>= 12.13.0'} + peerDependencies: + webpack: 5.95.0 + + minimalistic-assert@1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + multicast-dns@7.2.5: + resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} + hasBin: true + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + negotiator@0.6.4: + resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} + engines: {node: '>= 0.6'} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + + node-emoji@2.2.0: + resolution: {integrity: sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==} + engines: {node: '>=18'} + + node-releases@2.0.37: + resolution: {integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-url@8.1.1: + resolution: {integrity: sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==} + engines: {node: '>=14.16'} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + nprogress@0.2.0: + resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + null-loader@4.0.1: + resolution: {integrity: sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: 5.95.0 + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + obuf@1.1.2: + resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + on-headers@1.1.0: + resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==} + engines: {node: '>= 0.8'} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + open@10.2.0: + resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} + engines: {node: '>=18'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + + opener@1.5.2: + resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} + hasBin: true + + p-cancelable@3.0.0: + resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} + engines: {node: '>=12.20'} + + p-finally@1.0.0: + resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} + engines: {node: '>=4'} + + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + + p-queue@6.6.2: + resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} + engines: {node: '>=8'} + + p-retry@6.2.1: + resolution: {integrity: sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==} + engines: {node: '>=16.17'} + + p-timeout@3.2.0: + resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} + engines: {node: '>=8'} + + package-json@8.1.1: + resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==} + engines: {node: '>=14.16'} + + param-case@3.0.4: + resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse-numeric-range@1.3.0: + resolution: {integrity: sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==} + + parse5-htmlparser2-tree-adapter@7.1.0: + resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + pascal-case@3.1.2: + resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + + path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + path-is-inside@1.0.2: + resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-to-regexp@0.1.13: + resolution: {integrity: sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==} + + path-to-regexp@1.9.0: + resolution: {integrity: sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==} + + path-to-regexp@3.3.0: + resolution: {integrity: sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + + pkg-dir@7.0.0: + resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==} + engines: {node: '>=14.16'} + + pkijs@3.4.0: + resolution: {integrity: sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw==} + engines: {node: '>=16.0.0'} + + postcss-attribute-case-insensitive@7.0.1: + resolution: {integrity: sha512-Uai+SupNSqzlschRyNx3kbCTWgY/2hcwtHEI/ej2LJWc9JJ77qKgGptd8DHwY1mXtZ7Aoh4z4yxfwMBue9eNgw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-calc@9.0.1: + resolution: {integrity: sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.2.2 + + postcss-clamp@4.1.0: + resolution: {integrity: sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==} + engines: {node: '>=7.6.0'} + peerDependencies: + postcss: ^8.4.6 + + postcss-color-functional-notation@7.0.12: + resolution: {integrity: sha512-TLCW9fN5kvO/u38/uesdpbx3e8AkTYhMvDZYa9JpmImWuTE99bDQ7GU7hdOADIZsiI9/zuxfAJxny/khknp1Zw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-color-hex-alpha@10.0.0: + resolution: {integrity: sha512-1kervM2cnlgPs2a8Vt/Qbe5cQ++N7rkYo/2rz2BkqJZIHQwaVuJgQH38REHrAi4uM0b1fqxMkWYmese94iMp3w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-color-rebeccapurple@10.0.0: + resolution: {integrity: sha512-JFta737jSP+hdAIEhk1Vs0q0YF5P8fFcj+09pweS8ktuGuZ8pPlykHsk6mPxZ8awDl4TrcxUqJo9l1IhVr/OjQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-colormin@6.1.0: + resolution: {integrity: sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-convert-values@6.1.0: + resolution: {integrity: sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-custom-media@11.0.6: + resolution: {integrity: sha512-C4lD4b7mUIw+RZhtY7qUbf4eADmb7Ey8BFA2px9jUbwg7pjTZDl4KY4bvlUV+/vXQvzQRfiGEVJyAbtOsCMInw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-custom-properties@14.0.6: + resolution: {integrity: sha512-fTYSp3xuk4BUeVhxCSJdIPhDLpJfNakZKoiTDx7yRGCdlZrSJR7mWKVOBS4sBF+5poPQFMj2YdXx1VHItBGihQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-custom-selectors@8.0.5: + resolution: {integrity: sha512-9PGmckHQswiB2usSO6XMSswO2yFWVoCAuih1yl9FVcwkscLjRKjwsjM3t+NIWpSU2Jx3eOiK2+t4vVTQaoCHHg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-dir-pseudo-class@9.0.1: + resolution: {integrity: sha512-tRBEK0MHYvcMUrAuYMEOa0zg9APqirBcgzi6P21OhxtJyJADo/SWBwY1CAwEohQ/6HDaa9jCjLRG7K3PVQYHEA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-discard-comments@6.0.2: + resolution: {integrity: sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-duplicates@6.0.3: + resolution: {integrity: sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-empty@6.0.3: + resolution: {integrity: sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-overridden@6.0.2: + resolution: {integrity: sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-unused@6.0.5: + resolution: {integrity: sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-double-position-gradients@6.0.4: + resolution: {integrity: sha512-m6IKmxo7FxSP5nF2l63QbCC3r+bWpFUWmZXZf096WxG0m7Vl1Q1+ruFOhpdDRmKrRS+S3Jtk+TVk/7z0+BVK6g==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-focus-visible@10.0.1: + resolution: {integrity: sha512-U58wyjS/I1GZgjRok33aE8juW9qQgQUNwTSdxQGuShHzwuYdcklnvK/+qOWX1Q9kr7ysbraQ6ht6r+udansalA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-focus-within@9.0.1: + resolution: {integrity: sha512-fzNUyS1yOYa7mOjpci/bR+u+ESvdar6hk8XNK/TRR0fiGTp2QT5N+ducP0n3rfH/m9I7H/EQU6lsa2BrgxkEjw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-font-variant@5.0.0: + resolution: {integrity: sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==} + peerDependencies: + postcss: ^8.1.0 + + postcss-gap-properties@6.0.0: + resolution: {integrity: sha512-Om0WPjEwiM9Ru+VhfEDPZJAKWUd0mV1HmNXqp2C29z80aQ2uP9UVhLc7e3aYMIor/S5cVhoPgYQ7RtfeZpYTRw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-image-set-function@7.0.0: + resolution: {integrity: sha512-QL7W7QNlZuzOwBTeXEmbVckNt1FSmhQtbMRvGGqqU4Nf4xk6KUEQhAoWuMzwbSv5jxiRiSZ5Tv7eiDB9U87znA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-lab-function@7.0.12: + resolution: {integrity: sha512-tUcyRk1ZTPec3OuKFsqtRzW2Go5lehW29XA21lZ65XmzQkz43VY2tyWEC202F7W3mILOjw0voOiuxRGTsN+J9w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-loader@7.3.4: + resolution: {integrity: sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==} + engines: {node: '>= 14.15.0'} + peerDependencies: + postcss: ^7.0.0 || ^8.0.1 + webpack: 5.95.0 + + postcss-logical@8.1.0: + resolution: {integrity: sha512-pL1hXFQ2fEXNKiNiAgtfA005T9FBxky5zkX6s4GZM2D8RkVgRqz3f4g1JUoq925zXv495qk8UNldDwh8uGEDoA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-merge-idents@6.0.3: + resolution: {integrity: sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-merge-longhand@6.0.5: + resolution: {integrity: sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-merge-rules@6.1.1: + resolution: {integrity: sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-font-values@6.1.0: + resolution: {integrity: sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-gradients@6.0.3: + resolution: {integrity: sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-params@6.1.0: + resolution: {integrity: sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-selectors@6.0.4: + resolution: {integrity: sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-modules-extract-imports@3.1.0: + resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-local-by-default@4.2.0: + resolution: {integrity: sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-scope@3.2.1: + resolution: {integrity: sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-values@4.0.0: + resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-nesting@13.0.2: + resolution: {integrity: sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-normalize-charset@6.0.2: + resolution: {integrity: sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-display-values@6.0.2: + resolution: {integrity: sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-positions@6.0.2: + resolution: {integrity: sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-repeat-style@6.0.2: + resolution: {integrity: sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-string@6.0.2: + resolution: {integrity: sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-timing-functions@6.0.2: + resolution: {integrity: sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-unicode@6.1.0: + resolution: {integrity: sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-url@6.0.2: + resolution: {integrity: sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-whitespace@6.0.2: + resolution: {integrity: sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-opacity-percentage@3.0.0: + resolution: {integrity: sha512-K6HGVzyxUxd/VgZdX04DCtdwWJ4NGLG212US4/LA1TLAbHgmAsTWVR86o+gGIbFtnTkfOpb9sCRBx8K7HO66qQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-ordered-values@6.0.2: + resolution: {integrity: sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-overflow-shorthand@6.0.0: + resolution: {integrity: sha512-BdDl/AbVkDjoTofzDQnwDdm/Ym6oS9KgmO7Gr+LHYjNWJ6ExORe4+3pcLQsLA9gIROMkiGVjjwZNoL/mpXHd5Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-page-break@3.0.4: + resolution: {integrity: sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==} + peerDependencies: + postcss: ^8 + + postcss-place@10.0.0: + resolution: {integrity: sha512-5EBrMzat2pPAxQNWYavwAfoKfYcTADJ8AXGVPcUZ2UkNloUTWzJQExgrzrDkh3EKzmAx1evfTAzF9I8NGcc+qw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-preset-env@10.6.1: + resolution: {integrity: sha512-yrk74d9EvY+W7+lO9Aj1QmjWY9q5NsKjK2V9drkOPZB/X6KZ0B3igKsHUYakb7oYVhnioWypQX3xGuePf89f3g==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-pseudo-class-any-link@10.0.1: + resolution: {integrity: sha512-3el9rXlBOqTFaMFkWDOkHUTQekFIYnaQY55Rsp8As8QQkpiSgIYEcF/6Ond93oHiDsGb4kad8zjt+NPlOC1H0Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-reduce-idents@6.0.3: + resolution: {integrity: sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-reduce-initial@6.1.0: + resolution: {integrity: sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-reduce-transforms@6.0.2: + resolution: {integrity: sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-replace-overflow-wrap@4.0.0: + resolution: {integrity: sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==} + peerDependencies: + postcss: ^8.0.3 + + postcss-selector-not@8.0.1: + resolution: {integrity: sha512-kmVy/5PYVb2UOhy0+LqUYAhKj7DUGDpSWa5LZqlkWJaaAV+dxxsOG3+St0yNLu6vsKD7Dmqx+nWQt0iil89+WA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-selector-parser@7.1.1: + resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} + engines: {node: '>=4'} + + postcss-sort-media-queries@5.2.0: + resolution: {integrity: sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.4.23 + + postcss-svgo@6.0.3: + resolution: {integrity: sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==} + engines: {node: ^14 || ^16 || >= 18} + peerDependencies: + postcss: ^8.4.31 + + postcss-unique-selectors@6.0.4: + resolution: {integrity: sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss-zindex@6.0.2: + resolution: {integrity: sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss@8.5.9: + resolution: {integrity: sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==} + engines: {node: ^10 || ^12 || >=14} + + pretty-error@4.0.0: + resolution: {integrity: sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==} + + pretty-time@1.1.0: + resolution: {integrity: sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==} + engines: {node: '>=4'} + + prism-react-renderer@2.4.1: + resolution: {integrity: sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==} + peerDependencies: + react: '>=16.0.0' + + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} + engines: {node: '>=6'} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + + proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pupa@3.3.0: + resolution: {integrity: sha512-LjgDO2zPtoXP2wJpDjZrGdojii1uqO0cnwKoIoUzkfS98HDmbeiGmYiXo3lXeFlq2xvne1QFQhwYXSUCLKtEuA==} + engines: {node: '>=12.20'} + + pvtsutils@1.3.6: + resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} + + pvutils@1.1.5: + resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} + engines: {node: '>=16.0.0'} + + qs@6.14.2: + resolution: {integrity: sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==} + engines: {node: '>=0.6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + range-parser@1.2.0: + resolution: {integrity: sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==} + engines: {node: '>= 0.6'} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.3: + resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} + engines: {node: '>= 0.8'} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react-fast-compare@3.2.2: + resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-json-view-lite@2.5.0: + resolution: {integrity: sha512-tk7o7QG9oYyELWHL8xiMQ8x4WzjCzbWNyig3uexmkLb54r8jO0yH3WCWx8UZS0c49eSA4QUmG5caiRJ8fAn58g==} + engines: {node: '>=18'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + + react-loadable-ssr-addon-v5-slorber@1.0.3: + resolution: {integrity: sha512-GXfh9VLwB5ERaCsU6RULh7tkemeX15aNh6wuMEBtfdyMa7fFG8TXrhXlx1SoEK2Ty/l6XIkzzYIQmyaWW3JgdQ==} + engines: {node: '>=10.13.0'} + peerDependencies: + react-loadable: '*' + webpack: 5.95.0 + + react-router-config@5.1.1: + resolution: {integrity: sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==} + peerDependencies: + react: '>=15' + react-router: '>=5' + + react-router-dom@5.3.4: + resolution: {integrity: sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==} + peerDependencies: + react: '>=15' + + react-router@5.3.4: + resolution: {integrity: sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==} + peerDependencies: + react: '>=15' + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.1: + resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + + reflect-metadata@0.2.2: + resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} + + regenerate-unicode-properties@10.2.2: + resolution: {integrity: sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==} + engines: {node: '>=4'} + + regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + + regexpu-core@6.4.0: + resolution: {integrity: sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==} + engines: {node: '>=4'} + + registry-auth-token@5.1.1: + resolution: {integrity: sha512-P7B4+jq8DeD2nMsAcdfaqHbssgHtZ7Z5+++a5ask90fvmJ8p5je4mOa+wzu+DB4vQ5tdJV/xywY+UnVFeQLV5Q==} + engines: {node: '>=14'} + + registry-url@6.0.1: + resolution: {integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==} + engines: {node: '>=12'} + + regjsgen@0.8.0: + resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} + + regjsparser@0.13.1: + resolution: {integrity: sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==} + hasBin: true + + rehype-raw@7.0.0: + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + + relateurl@0.2.7: + resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} + engines: {node: '>= 0.10'} + + remark-directive@3.0.1: + resolution: {integrity: sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==} + + remark-emoji@4.0.1: + resolution: {integrity: sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + remark-frontmatter@5.0.0: + resolution: {integrity: sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-mdx@3.1.1: + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + renderkid@3.0.0: + resolution: {integrity: sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==} + + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + require-like@0.1.2: + resolution: {integrity: sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pathname@3.0.0: + resolution: {integrity: sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==} + + resolve@1.22.12: + resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} + engines: {node: '>= 0.4'} + hasBin: true + + responselike@3.0.0: + resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} + engines: {node: '>=14.16'} + + retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rtlcss@4.3.0: + resolution: {integrity: sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==} + engines: {node: '>=12.0.0'} + hasBin: true + + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sax@1.6.0: + resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} + engines: {node: '>=11.0.0'} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + schema-dts@1.1.5: + resolution: {integrity: sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg==} + + schema-utils@3.3.0: + resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} + engines: {node: '>= 10.13.0'} + + schema-utils@4.3.3: + resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} + engines: {node: '>= 10.13.0'} + + search-insights@2.17.3: + resolution: {integrity: sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==} + + section-matter@1.0.0: + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} + + select-hose@2.0.0: + resolution: {integrity: sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==} + + selfsigned@5.5.0: + resolution: {integrity: sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew==} + engines: {node: '>=18'} + + semver-diff@4.0.0: + resolution: {integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==} + engines: {node: '>=12'} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + send@0.19.2: + resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} + engines: {node: '>= 0.8.0'} + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + + serve-handler@6.1.7: + resolution: {integrity: sha512-CinAq1xWb0vR3twAv9evEU8cNWkXCb9kd5ePAHUKJBkOsUpR1wt/CvGdeca7vqumL1U5cSaeVQ6zZMxiJ3yWsg==} + + serve-index@1.9.2: + resolution: {integrity: sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ==} + engines: {node: '>= 0.8.0'} + + serve-static@1.16.3: + resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} + engines: {node: '>= 0.8.0'} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + shallow-clone@3.0.1: + resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} + engines: {node: '>=8'} + + shallowequal@1.1.0: + resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.8.3: + resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} + engines: {node: '>= 0.4'} + + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + sirv@2.0.4: + resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} + engines: {node: '>= 10'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + sitemap@7.1.3: + resolution: {integrity: sha512-tAjEd+wt/YwnEbfNB2ht51ybBJxbEWwe5ki/Z//Wh0rpBFTCUSj46GnxUKEWzhfuJTsee8x3lybHxFgUMig2hw==} + engines: {node: '>=12.0.0', npm: '>=5.6.0'} + hasBin: true + + skin-tone@2.0.0: + resolution: {integrity: sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==} + engines: {node: '>=8'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slash@4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + + snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + + sockjs@0.3.24: + resolution: {integrity: sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==} + + sort-css-media-queries@2.2.0: + resolution: {integrity: sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==} + engines: {node: '>= 6.3.0'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + spdy-transport@3.0.0: + resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} + + spdy@4.0.2: + resolution: {integrity: sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==} + engines: {node: '>=6.0.0'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + srcset@4.0.0: + resolution: {integrity: sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==} + engines: {node: '>=12'} + + statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + stringify-object@3.3.0: + resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} + engines: {node: '>=4'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + strip-bom-string@1.0.0: + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} + engines: {node: '>=0.10.0'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + style-to-js@1.1.21: + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + + style-to-object@1.0.14: + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + + stylehacks@6.1.1: + resolution: {integrity: sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svg-parser@2.0.4: + resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} + + svgo@3.3.3: + resolution: {integrity: sha512-+wn7I4p7YgJhHs38k2TNjy1vCfPIfLIJWR5MnCStsN8WuuTcBnRKcMHQLMM2ijxGZmDoZwNv8ipl5aTTen62ng==} + engines: {node: '>=14.0.0'} + hasBin: true + + tapable@2.3.2: + resolution: {integrity: sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==} + engines: {node: '>=6'} + + terser-webpack-plugin@5.4.0: + resolution: {integrity: sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: 5.95.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + + terser@5.46.1: + resolution: {integrity: sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ==} + engines: {node: '>=10'} + hasBin: true + + thingies@2.6.0: + resolution: {integrity: sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==} + engines: {node: '>=10.18'} + peerDependencies: + tslib: ^2 + + thunky@1.1.0: + resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tiny-warning@1.0.3: + resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} + + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} + engines: {node: ^18.0.0 || >=20.0.0} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + tree-dump@1.1.0: + resolution: {integrity: sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsyringe@4.10.0: + resolution: {integrity: sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==} + engines: {node: '>= 6.0.0'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + + type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + typedarray-to-buffer@3.1.5: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@7.19.2: + resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==} + + unicode-canonical-property-names-ecmascript@2.0.1: + resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} + engines: {node: '>=4'} + + unicode-emoji-modifier-base@1.0.0: + resolution: {integrity: sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==} + engines: {node: '>=4'} + + unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + + unicode-match-property-value-ecmascript@2.2.1: + resolution: {integrity: sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==} + engines: {node: '>=4'} + + unicode-property-aliases-ecmascript@2.2.0: + resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==} + engines: {node: '>=4'} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unique-string@3.0.0: + resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} + engines: {node: '>=12'} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + update-notifier@6.0.2: + resolution: {integrity: sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==} + engines: {node: '>=14.16'} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + url-loader@4.1.1: + resolution: {integrity: sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==} + engines: {node: '>= 10.13.0'} + peerDependencies: + file-loader: '*' + webpack: 5.95.0 + peerDependenciesMeta: + file-loader: + optional: true + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + utila@0.4.0: + resolution: {integrity: sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==} + + utility-types@3.11.0: + resolution: {integrity: sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==} + engines: {node: '>= 4'} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + value-equal@1.0.1: + resolution: {integrity: sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + watchpack@2.5.1: + resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} + engines: {node: '>=10.13.0'} + + wbuf@1.7.3: + resolution: {integrity: sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==} + + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + + webpack-bundle-analyzer@4.10.2: + resolution: {integrity: sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==} + engines: {node: '>= 10.13.0'} + hasBin: true + + webpack-dev-middleware@7.4.5: + resolution: {integrity: sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA==} + engines: {node: '>= 18.12.0'} + peerDependencies: + webpack: 5.95.0 + peerDependenciesMeta: + webpack: + optional: true + + webpack-dev-server@5.2.3: + resolution: {integrity: sha512-9Gyu2F7+bg4Vv+pjbovuYDhHX+mqdqITykfzdM9UyKqKHlsE5aAjRhR+oOEfXW5vBeu8tarzlJFIZva4ZjAdrQ==} + engines: {node: '>= 18.12.0'} + hasBin: true + peerDependencies: + webpack: 5.95.0 + webpack-cli: '*' + peerDependenciesMeta: + webpack: + optional: true + webpack-cli: + optional: true + + webpack-merge@5.10.0: + resolution: {integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==} + engines: {node: '>=10.0.0'} + + webpack-merge@6.0.1: + resolution: {integrity: sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==} + engines: {node: '>=18.0.0'} + + webpack-sources@3.3.4: + resolution: {integrity: sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==} + engines: {node: '>=10.13.0'} + + webpack@5.106.1: + resolution: {integrity: sha512-EW8af29ak8Oaf4T8k8YsajjrDBDYgnKZ5er6ljWFJsXABfTNowQfvHLftwcepVgdz+IoLSdEAbBiM9DFXoll9w==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + + webpack@5.95.0: + resolution: {integrity: sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + + webpackbar@6.0.1: + resolution: {integrity: sha512-TnErZpmuKdwWBdMoexjio3KKX6ZtoKHRVvLIU0A47R0VVBDtx3ZyOJDktgYixhoJokZTYTt1Z37OkO9pnGJa9Q==} + engines: {node: '>=14.21.3'} + peerDependencies: + webpack: 5.95.0 + + websocket-driver@0.7.4: + resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} + engines: {node: '>=0.8.0'} + + websocket-extensions@0.1.4: + resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==} + engines: {node: '>=0.8.0'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + widest-line@4.0.1: + resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==} + engines: {node: '>=12'} + + wildcard@2.0.1: + resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + write-file-atomic@3.0.3: + resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.20.0: + resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + wsl-utils@0.1.0: + resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} + engines: {node: '>=18'} + + xdg-basedir@5.1.0: + resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==} + engines: {node: '>=12'} + + xml-js@1.6.11: + resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==} + hasBin: true + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} + engines: {node: '>=12.20'} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@algolia/abtesting@1.16.1': + dependencies: + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + '@algolia/autocomplete-core@1.19.2(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)(search-insights@2.17.3)': + dependencies: + '@algolia/autocomplete-plugin-algolia-insights': 1.19.2(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)(search-insights@2.17.3) + '@algolia/autocomplete-shared': 1.19.2(@algolia/client-search@5.50.1)(algoliasearch@5.50.1) + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + - search-insights + + '@algolia/autocomplete-plugin-algolia-insights@1.19.2(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)(search-insights@2.17.3)': + dependencies: + '@algolia/autocomplete-shared': 1.19.2(@algolia/client-search@5.50.1)(algoliasearch@5.50.1) + search-insights: 2.17.3 + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + + '@algolia/autocomplete-shared@1.19.2(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)': + dependencies: + '@algolia/client-search': 5.50.1 + algoliasearch: 5.50.1 + + '@algolia/client-abtesting@5.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + '@algolia/client-analytics@5.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + '@algolia/client-common@5.50.1': {} + + '@algolia/client-insights@5.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + '@algolia/client-personalization@5.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + '@algolia/client-query-suggestions@5.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + '@algolia/client-search@5.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + '@algolia/events@4.0.1': {} + + '@algolia/ingestion@1.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + '@algolia/monitoring@1.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + '@algolia/recommend@5.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + '@algolia/requester-browser-xhr@5.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + + '@algolia/requester-fetch@5.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + + '@algolia/requester-node-http@5.50.1': + dependencies: + '@algolia/client-common': 5.50.1 + + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.0': {} + + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.29.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + regexpu-core: 6.4.0 + semver: 6.3.1 + + '@babel/helper-define-polyfill-provider@0.6.8(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + debug: 4.4.3 + lodash.debounce: 4.0.8 + resolve: 1.22.12 + transitivePeerDependencies: + - supports-color + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-member-expression-to-functions@7.28.5': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-plugin-utils@7.28.6': {} + + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-wrap-function': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helper-wrap-function@7.28.6': + dependencies: + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helpers@7.29.2': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + + '@babel/parser@7.29.2': + dependencies: + '@babel/types': 7.29.0 + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-import-assertions@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-async-generator-functions@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-static-block@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-classes@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-globals': 7.28.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/template': 7.28.6 + + '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-dotall-regex@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-explicit-resource-management@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-exponentiation-operator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-json-strings@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-logical-assignment-operators@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-systemjs@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-numeric-separator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-optional-catch-binding@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-private-property-in-object@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-react-constant-elements@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-regenerator@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-regexp-modifiers@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-runtime@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.0) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-spread@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-property-regex@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-sets-regex@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/preset-env@7.29.2(@babel/core@7.29.0)': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0) + '@babel/plugin-syntax-import-assertions': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-async-generator-functions': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-static-block': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-classes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-computed-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-dotall-regex': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-explicit-resource-management': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-exponentiation-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-json-strings': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-logical-assignment-operators': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-systemjs': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-numeric-separator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-rest-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-optional-catch-binding': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-regenerator': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-regexp-modifiers': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-property-regex': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-sets-regex': 7.28.6(@babel/core@7.29.0) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.0) + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.14.2(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.0) + core-js-compat: 3.49.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/types': 7.29.0 + esutils: 2.0.3 + + '@babel/preset-react@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/runtime-corejs3@7.29.2': + dependencies: + core-js-pure: 3.49.0 + + '@babel/runtime@7.29.2': {} + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@colors/colors@1.5.0': + optional: true + + '@csstools/cascade-layer-name-parser@2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/color-helpers@5.1.0': {} + + '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/color-helpers': 5.1.0 + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-tokenizer@3.0.4': {} + + '@csstools/media-query-list-parser@4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/postcss-alpha-function@1.0.1(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-cascade-layers@5.0.2(postcss@8.5.9)': + dependencies: + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1) + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + '@csstools/postcss-color-function-display-p3-linear@1.0.1(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-color-function@4.0.12(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-color-mix-function@3.0.12(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-color-mix-variadic-function-arguments@1.0.2(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-content-alt-text@2.0.8(postcss@8.5.9)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-contrast-color-function@2.0.12(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-exponential-functions@2.0.9(postcss@8.5.9)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.9 + + '@csstools/postcss-font-format-keywords@4.0.0(postcss@8.5.9)': + dependencies: + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-gamut-mapping@2.0.11(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.9 + + '@csstools/postcss-gradients-interpolation-method@5.0.12(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-hwb-function@4.0.12(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-ic-unit@4.0.4(postcss@8.5.9)': + dependencies: + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-initial@2.0.1(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + + '@csstools/postcss-is-pseudo-class@5.0.3(postcss@8.5.9)': + dependencies: + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1) + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + '@csstools/postcss-light-dark-function@2.0.11(postcss@8.5.9)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-logical-float-and-clear@3.0.0(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + + '@csstools/postcss-logical-overflow@2.0.0(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + + '@csstools/postcss-logical-overscroll-behavior@2.0.0(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + + '@csstools/postcss-logical-resize@3.0.0(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-logical-viewport-units@3.0.4(postcss@8.5.9)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-media-minmax@2.0.9(postcss@8.5.9)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/media-query-list-parser': 4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + postcss: 8.5.9 + + '@csstools/postcss-media-queries-aspect-ratio-number-values@3.0.5(postcss@8.5.9)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/media-query-list-parser': 4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + postcss: 8.5.9 + + '@csstools/postcss-nested-calc@4.0.0(postcss@8.5.9)': + dependencies: + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-normalize-display-values@4.0.1(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-oklab-function@4.0.12(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-position-area-property@1.0.0(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + + '@csstools/postcss-progressive-custom-properties@4.2.1(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-property-rule-prelude-list@1.0.0(postcss@8.5.9)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.9 + + '@csstools/postcss-random-function@2.0.1(postcss@8.5.9)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.9 + + '@csstools/postcss-relative-color-syntax@3.0.12(postcss@8.5.9)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + '@csstools/postcss-scope-pseudo-class@4.0.1(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + '@csstools/postcss-sign-functions@1.1.4(postcss@8.5.9)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.9 + + '@csstools/postcss-stepped-value-functions@4.0.9(postcss@8.5.9)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.9 + + '@csstools/postcss-syntax-descriptor-syntax-production@1.0.1(postcss@8.5.9)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.9 + + '@csstools/postcss-system-ui-font-family@1.0.0(postcss@8.5.9)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.9 + + '@csstools/postcss-text-decoration-shorthand@4.0.3(postcss@8.5.9)': + dependencies: + '@csstools/color-helpers': 5.1.0 + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-trigonometric-functions@4.0.9(postcss@8.5.9)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.9 + + '@csstools/postcss-unset-value@4.0.0(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + + '@csstools/selector-resolve-nested@3.1.0(postcss-selector-parser@7.1.1)': + dependencies: + postcss-selector-parser: 7.1.1 + + '@csstools/selector-specificity@5.0.0(postcss-selector-parser@7.1.1)': + dependencies: + postcss-selector-parser: 7.1.1 + + '@csstools/utilities@2.0.0(postcss@8.5.9)': + dependencies: + postcss: 8.5.9 + + '@discoveryjs/json-ext@0.5.7': {} + + '@docsearch/core@4.6.2(@types/react@19.2.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + optionalDependencies: + '@types/react': 19.2.14 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@docsearch/css@4.6.2': {} + + '@docsearch/react@4.6.2(@algolia/client-search@5.50.1)(@types/react@19.2.14)(algoliasearch@5.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)': + dependencies: + '@algolia/autocomplete-core': 1.19.2(@algolia/client-search@5.50.1)(algoliasearch@5.50.1)(search-insights@2.17.3) + '@docsearch/core': 4.6.2(@types/react@19.2.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docsearch/css': 4.6.2 + optionalDependencies: + '@types/react': 19.2.14 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + search-insights: 2.17.3 + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + + '@docusaurus/babel@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) + '@babel/preset-env': 7.29.2(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) + '@babel/runtime': 7.29.2 + '@babel/runtime-corejs3': 7.29.2 + '@babel/traverse': 7.29.0 + '@docusaurus/logger': 3.9.2 + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + babel-plugin-dynamic-import-node: 2.3.3 + fs-extra: 11.3.4 + tslib: 2.8.1 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/bundler@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + dependencies: + '@babel/core': 7.29.0 + '@docusaurus/babel': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/cssnano-preset': 3.9.2 + '@docusaurus/logger': 3.9.2 + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + babel-loader: 9.2.1(@babel/core@7.29.0)(webpack@5.95.0) + clean-css: 5.3.3 + copy-webpack-plugin: 11.0.0(webpack@5.95.0) + css-loader: 6.11.0(webpack@5.95.0) + css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(webpack@5.95.0) + cssnano: 6.1.2(postcss@8.5.9) + file-loader: 6.2.0(webpack@5.95.0) + html-minifier-terser: 7.2.0 + mini-css-extract-plugin: 2.10.2(webpack@5.95.0) + null-loader: 4.0.1(webpack@5.95.0) + postcss: 8.5.9 + postcss-loader: 7.3.4(postcss@8.5.9)(typescript@5.9.3)(webpack@5.95.0) + postcss-preset-env: 10.6.1(postcss@8.5.9) + terser-webpack-plugin: 5.4.0(webpack@5.95.0) + tslib: 2.8.1 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.106.1))(webpack@5.95.0) + webpack: 5.95.0 + webpackbar: 6.0.1(webpack@5.95.0) + transitivePeerDependencies: + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - csso + - esbuild + - lightningcss + - react + - react-dom + - supports-color + - typescript + - uglify-js + - webpack-cli + + '@docusaurus/core@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + dependencies: + '@docusaurus/babel': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/bundler': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@18.3.1) + boxen: 6.2.1 + chalk: 4.1.2 + chokidar: 3.6.0 + cli-table3: 0.6.5 + combine-promises: 1.2.0 + commander: 5.1.0 + core-js: 3.49.0 + detect-port: 1.6.1 + escape-html: 1.0.3 + eta: 2.2.0 + eval: 0.1.8 + execa: 5.1.1 + fs-extra: 11.3.4 + html-tags: 3.3.1 + html-webpack-plugin: 5.6.6(webpack@5.95.0) + leven: 3.1.0 + lodash: 4.18.1 + open: 8.4.2 + p-map: 4.0.0 + prompts: 2.4.2 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)' + react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' + react-loadable-ssr-addon-v5-slorber: 1.0.3(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.95.0) + react-router: 5.3.4(react@18.3.1) + react-router-config: 5.1.1(react-router@5.3.4(react@18.3.1))(react@18.3.1) + react-router-dom: 5.3.4(react@18.3.1) + semver: 7.7.4 + serve-handler: 6.1.7 + tinypool: 1.1.1 + tslib: 2.8.1 + update-notifier: 6.0.2 + webpack: 5.95.0 + webpack-bundle-analyzer: 4.10.2 + webpack-dev-server: 5.2.3(tslib@2.8.1)(webpack@5.95.0) + webpack-merge: 6.0.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/cssnano-preset@3.9.2': + dependencies: + cssnano-preset-advanced: 6.1.2(postcss@8.5.9) + postcss: 8.5.9 + postcss-sort-media-queries: 5.2.0(postcss@8.5.9) + tslib: 2.8.1 + + '@docusaurus/logger@3.9.2': + dependencies: + chalk: 4.1.2 + tslib: 2.8.1 + + '@docusaurus/mdx-loader@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@docusaurus/logger': 3.9.2 + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mdx-js/mdx': 3.1.1 + '@slorber/remark-comment': 1.0.0 + escape-html: 1.0.3 + estree-util-value-to-estree: 3.5.0 + file-loader: 6.2.0(webpack@5.95.0) + fs-extra: 11.3.4 + image-size: 2.0.2 + mdast-util-mdx: 3.0.0 + mdast-util-to-string: 4.0.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + rehype-raw: 7.0.0 + remark-directive: 3.0.1 + remark-emoji: 4.0.1 + remark-frontmatter: 5.0.0 + remark-gfm: 4.0.1 + stringify-object: 3.3.0 + tslib: 2.8.1 + unified: 11.0.5 + unist-util-visit: 5.1.0 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.106.1))(webpack@5.95.0) + vfile: 6.0.3 + webpack: 5.95.0 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/module-type-aliases@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@types/history': 4.7.11 + '@types/react': 19.2.14 + '@types/react-router-config': 5.0.11 + '@types/react-router-dom': 5.3.3 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)' + react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' + transitivePeerDependencies: + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/plugin-content-blog@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + cheerio: 1.0.0-rc.12 + feed: 4.2.2 + fs-extra: 11.3.4 + lodash: 4.18.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + schema-dts: 1.1.5 + srcset: 4.0.0 + tslib: 2.8.1 + unist-util-visit: 5.1.0 + utility-types: 3.11.0 + webpack: 5.95.0 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@types/react-router-config': 5.0.11 + combine-promises: 1.2.0 + fs-extra: 11.3.4 + js-yaml: 4.1.1 + lodash: 4.18.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + schema-dts: 1.1.5 + tslib: 2.8.1 + utility-types: 3.11.0 + webpack: 5.95.0 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-content-pages@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + fs-extra: 11.3.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tslib: 2.8.1 + webpack: 5.95.0 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-css-cascade-layers@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - react + - react-dom + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-debug@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + fs-extra: 11.3.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-json-view-lite: 2.5.0(react@18.3.1) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-google-analytics@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-google-gtag@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@types/gtag.js': 0.0.12 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-google-tag-manager@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-sitemap@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + fs-extra: 11.3.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + sitemap: 7.1.3 + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-svgr@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@svgr/core': 8.1.0(typescript@5.9.3) + '@svgr/webpack': 8.1.0(typescript@5.9.3) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tslib: 2.8.1 + webpack: 5.95.0 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/preset-classic@3.9.2(@algolia/client-search@5.50.1)(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(@types/react@19.2.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-css-cascade-layers': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-debug': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-google-analytics': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-google-gtag': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-google-tag-manager': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-sitemap': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-svgr': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/theme-classic': 3.9.2(@types/react@19.2.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-search-algolia': 3.9.2(@algolia/client-search@5.50.1)(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(@types/react@19.2.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.3) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + transitivePeerDependencies: + - '@algolia/client-search' + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - '@types/react' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - search-insights + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/react-loadable@6.0.0(react@18.3.1)': + dependencies: + '@types/react': 19.2.14 + react: 18.3.1 + + '@docusaurus/theme-classic@3.9.2(@types/react@19.2.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-translations': 3.9.2 + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@18.3.1) + clsx: 2.1.1 + infima: 0.2.0-alpha.45 + lodash: 4.18.1 + nprogress: 0.2.0 + postcss: 8.5.9 + prism-react-renderer: 2.4.1(react@18.3.1) + prismjs: 1.30.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-router-dom: 5.3.4(react@18.3.1) + rtlcss: 4.3.0 + tslib: 2.8.1 + utility-types: 3.11.0 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - '@types/react' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/theme-common@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@types/history': 4.7.11 + '@types/react': 19.2.14 + '@types/react-router-config': 5.0.11 + clsx: 2.1.1 + parse-numeric-range: 1.3.0 + prism-react-renderer: 2.4.1(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tslib: 2.8.1 + utility-types: 3.11.0 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/theme-search-algolia@3.9.2(@algolia/client-search@5.50.1)(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(@types/react@19.2.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.3)': + dependencies: + '@docsearch/react': 4.6.2(@algolia/client-search@5.50.1)(@types/react@19.2.14)(algoliasearch@5.50.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-translations': 3.9.2 + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + algoliasearch: 5.50.1 + algoliasearch-helper: 3.28.1(algoliasearch@5.50.1) + clsx: 2.1.1 + eta: 2.2.0 + fs-extra: 11.3.4 + lodash: 4.18.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tslib: 2.8.1 + utility-types: 3.11.0 + transitivePeerDependencies: + - '@algolia/client-search' + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - '@types/react' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - search-insights + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/theme-translations@3.9.2': + dependencies: + fs-extra: 11.3.4 + tslib: 2.8.1 + + '@docusaurus/types@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@mdx-js/mdx': 3.1.1 + '@types/history': 4.7.11 + '@types/mdast': 4.0.4 + '@types/react': 19.2.14 + commander: 5.1.0 + joi: 17.13.3 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)' + utility-types: 3.11.0 + webpack: 5.95.0 + webpack-merge: 5.10.0 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/utils-common@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + tslib: 2.8.1 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/utils-validation@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@docusaurus/logger': 3.9.2 + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + fs-extra: 11.3.4 + joi: 17.13.3 + js-yaml: 4.1.1 + lodash: 4.18.1 + tslib: 2.8.1 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/utils@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@docusaurus/logger': 3.9.2 + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + escape-string-regexp: 4.0.0 + execa: 5.1.1 + file-loader: 6.2.0(webpack@5.95.0) + fs-extra: 11.3.4 + github-slugger: 1.5.0 + globby: 11.1.0 + gray-matter: 4.0.3 + jiti: 1.21.7 + js-yaml: 4.1.1 + lodash: 4.18.1 + micromatch: 4.0.8 + p-queue: 6.6.2 + prompts: 2.4.2 + resolve-pathname: 3.0.0 + tslib: 2.8.1 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.106.1))(webpack@5.95.0) + utility-types: 3.11.0 + webpack: 5.95.0 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli + + '@hapi/hoek@9.3.0': {} + + '@hapi/topo@5.1.0': + dependencies: + '@hapi/hoek': 9.3.0 + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.10 + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 25.6.0 + '@types/yargs': 17.0.35 + chalk: 4.1.2 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/source-map@0.3.11': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@jsonjoy.com/base64@1.1.2(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/base64@17.67.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/buffers@1.2.1(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/buffers@17.67.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/codegen@1.0.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/codegen@17.67.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/fs-core@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-fsa@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-core': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-builtins@4.57.1(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-to-fsa@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-fsa': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-utils@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-core': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.57.1(tslib@2.8.1) + glob-to-regex.js: 1.2.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-print@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-snapshot@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/json-pack': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pack@1.21.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/base64': 1.1.2(tslib@2.8.1) + '@jsonjoy.com/buffers': 1.2.1(tslib@2.8.1) + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + '@jsonjoy.com/json-pointer': 1.0.2(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + hyperdyperid: 1.2.0 + thingies: 2.6.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pack@17.67.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/base64': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/codegen': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/json-pointer': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) + hyperdyperid: 1.2.0 + thingies: 2.6.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pointer@1.0.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pointer@17.67.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/util@1.9.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 1.2.1(tslib@2.8.1) + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/util@17.67.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/codegen': 17.67.0(tslib@2.8.1) + tslib: 2.8.1 + + '@leichtgewicht/ip-codec@2.0.5': {} + + '@mdx-js/mdx@3.1.1': + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdx': 2.0.13 + acorn: 8.16.0 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-util-scope: 1.0.0 + estree-walker: 3.0.3 + hast-util-to-jsx-runtime: 2.3.6 + markdown-extensions: 2.0.0 + recma-build-jsx: 1.0.0 + recma-jsx: 1.0.1(acorn@8.16.0) + recma-stringify: 1.0.0 + rehype-recma: 1.0.0 + remark-mdx: 3.1.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + source-map: 0.7.6 + unified: 11.0.5 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@mdx-js/react@3.1.1(@types/react@19.2.14)(react@18.3.1)': + dependencies: + '@types/mdx': 2.0.13 + '@types/react': 19.2.14 + react: 18.3.1 + + '@noble/hashes@1.4.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@peculiar/asn1-cms@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + '@peculiar/asn1-x509-attr': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-csr@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-ecc@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-pfx@2.6.1': + dependencies: + '@peculiar/asn1-cms': 2.6.1 + '@peculiar/asn1-pkcs8': 2.6.1 + '@peculiar/asn1-rsa': 2.6.1 + '@peculiar/asn1-schema': 2.6.0 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-pkcs8@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-pkcs9@2.6.1': + dependencies: + '@peculiar/asn1-cms': 2.6.1 + '@peculiar/asn1-pfx': 2.6.1 + '@peculiar/asn1-pkcs8': 2.6.1 + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + '@peculiar/asn1-x509-attr': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-rsa@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-schema@2.6.0': + dependencies: + asn1js: 3.0.7 + pvtsutils: 1.3.6 + tslib: 2.8.1 + + '@peculiar/asn1-x509-attr@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-x509@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + asn1js: 3.0.7 + pvtsutils: 1.3.6 + tslib: 2.8.1 + + '@peculiar/x509@1.14.3': + dependencies: + '@peculiar/asn1-cms': 2.6.1 + '@peculiar/asn1-csr': 2.6.1 + '@peculiar/asn1-ecc': 2.6.1 + '@peculiar/asn1-pkcs9': 2.6.1 + '@peculiar/asn1-rsa': 2.6.1 + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + pvtsutils: 1.3.6 + reflect-metadata: 0.2.2 + tslib: 2.8.1 + tsyringe: 4.10.0 + + '@pnpm/config.env-replace@1.1.0': {} + + '@pnpm/network.ca-file@1.0.2': + dependencies: + graceful-fs: 4.2.10 + + '@pnpm/npm-conf@3.0.2': + dependencies: + '@pnpm/config.env-replace': 1.1.0 + '@pnpm/network.ca-file': 1.0.2 + config-chain: 1.1.13 + + '@polka/url@1.0.0-next.29': {} + + '@sideway/address@4.1.5': + dependencies: + '@hapi/hoek': 9.3.0 + + '@sideway/formula@3.0.1': {} + + '@sideway/pinpoint@2.0.0': {} + + '@sinclair/typebox@0.27.10': {} + + '@sindresorhus/is@4.6.0': {} + + '@sindresorhus/is@5.6.0': {} + + '@slorber/react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.29.2 + invariant: 2.2.4 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-fast-compare: 3.2.2 + shallowequal: 1.1.0 + + '@slorber/remark-comment@1.0.0': + dependencies: + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-preset@8.1.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.29.0) + '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.29.0) + + '@svgr/core@8.1.0(typescript@5.9.3)': + dependencies: + '@babel/core': 7.29.0 + '@svgr/babel-preset': 8.1.0(@babel/core@7.29.0) + camelcase: 6.3.0 + cosmiconfig: 8.3.6(typescript@5.9.3) + snake-case: 3.0.4 + transitivePeerDependencies: + - supports-color + - typescript + + '@svgr/hast-util-to-babel-ast@8.0.0': + dependencies: + '@babel/types': 7.29.0 + entities: 4.5.0 + + '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.9.3))': + dependencies: + '@babel/core': 7.29.0 + '@svgr/babel-preset': 8.1.0(@babel/core@7.29.0) + '@svgr/core': 8.1.0(typescript@5.9.3) + '@svgr/hast-util-to-babel-ast': 8.0.0 + svg-parser: 2.0.4 + transitivePeerDependencies: + - supports-color + + '@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@5.9.3))(typescript@5.9.3)': + dependencies: + '@svgr/core': 8.1.0(typescript@5.9.3) + cosmiconfig: 8.3.6(typescript@5.9.3) + deepmerge: 4.3.1 + svgo: 3.3.3 + transitivePeerDependencies: + - typescript + + '@svgr/webpack@8.1.0(typescript@5.9.3)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.29.0) + '@babel/preset-env': 7.29.2(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) + '@svgr/core': 8.1.0(typescript@5.9.3) + '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3)) + '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3))(typescript@5.9.3) + transitivePeerDependencies: + - supports-color + - typescript + + '@szmarczak/http-timer@5.0.1': + dependencies: + defer-to-connect: 2.0.1 + + '@types/body-parser@1.19.6': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 25.6.0 + + '@types/bonjour@3.5.13': + dependencies: + '@types/node': 25.6.0 + + '@types/connect-history-api-fallback@1.5.4': + dependencies: + '@types/express-serve-static-core': 4.19.8 + '@types/node': 25.6.0 + + '@types/connect@3.4.38': + dependencies: + '@types/node': 25.6.0 + + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + + '@types/eslint-scope@3.7.7': + dependencies: + '@types/eslint': 9.6.1 + '@types/estree': 1.0.8 + optional: true + + '@types/eslint@9.6.1': + dependencies: + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + optional: true + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.8 + + '@types/estree@1.0.8': {} + + '@types/express-serve-static-core@4.19.8': + dependencies: + '@types/node': 25.6.0 + '@types/qs': 6.15.0 + '@types/range-parser': 1.2.7 + '@types/send': 1.2.1 + + '@types/express@4.17.25': + dependencies: + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 4.19.8 + '@types/qs': 6.15.0 + '@types/serve-static': 1.15.10 + + '@types/gtag.js@0.0.12': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/history@4.7.11': {} + + '@types/html-minifier-terser@6.1.0': {} + + '@types/http-cache-semantics@4.2.0': {} + + '@types/http-errors@2.0.5': {} + + '@types/http-proxy@1.17.17': + dependencies: + '@types/node': 25.6.0 + + '@types/istanbul-lib-coverage@2.0.6': {} + + '@types/istanbul-lib-report@3.0.3': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + + '@types/istanbul-reports@3.0.4': + dependencies: + '@types/istanbul-lib-report': 3.0.3 + + '@types/json-schema@7.0.15': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdx@2.0.13': {} + + '@types/mime@1.3.5': {} + + '@types/ms@2.1.0': {} + + '@types/node@17.0.45': {} + + '@types/node@25.6.0': + dependencies: + undici-types: 7.19.2 + + '@types/prismjs@1.26.6': {} + + '@types/qs@6.15.0': {} + + '@types/range-parser@1.2.7': {} + + '@types/react-router-config@5.0.11': + dependencies: + '@types/history': 4.7.11 + '@types/react': 19.2.14 + '@types/react-router': 5.1.20 + + '@types/react-router-dom@5.3.3': + dependencies: + '@types/history': 4.7.11 + '@types/react': 19.2.14 + '@types/react-router': 5.1.20 + + '@types/react-router@5.1.20': + dependencies: + '@types/history': 4.7.11 + '@types/react': 19.2.14 + + '@types/react@19.2.14': + dependencies: + csstype: 3.2.3 + + '@types/retry@0.12.2': {} + + '@types/sax@1.2.7': + dependencies: + '@types/node': 25.6.0 + + '@types/send@0.17.6': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 25.6.0 + + '@types/send@1.2.1': + dependencies: + '@types/node': 25.6.0 + + '@types/serve-index@1.9.4': + dependencies: + '@types/express': 4.17.25 + + '@types/serve-static@1.15.10': + dependencies: + '@types/http-errors': 2.0.5 + '@types/node': 25.6.0 + '@types/send': 0.17.6 + + '@types/sockjs@0.3.36': + dependencies: + '@types/node': 25.6.0 + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + + '@types/ws@8.18.1': + dependencies: + '@types/node': 25.6.0 + + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.35': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@ungap/structured-clone@1.3.0': {} + + '@webassemblyjs/ast@1.14.1': + dependencies: + '@webassemblyjs/helper-numbers': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + + '@webassemblyjs/floating-point-hex-parser@1.13.2': {} + + '@webassemblyjs/helper-api-error@1.13.2': {} + + '@webassemblyjs/helper-buffer@1.14.1': {} + + '@webassemblyjs/helper-numbers@1.13.2': + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.13.2 + '@webassemblyjs/helper-api-error': 1.13.2 + '@xtuc/long': 4.2.2 + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} + + '@webassemblyjs/helper-wasm-section@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/wasm-gen': 1.14.1 + + '@webassemblyjs/ieee754@1.13.2': + dependencies: + '@xtuc/ieee754': 1.2.0 + + '@webassemblyjs/leb128@1.13.2': + dependencies: + '@xtuc/long': 4.2.2 + + '@webassemblyjs/utf8@1.13.2': {} + + '@webassemblyjs/wasm-edit@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/helper-wasm-section': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-opt': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + '@webassemblyjs/wast-printer': 1.14.1 + + '@webassemblyjs/wasm-gen@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wasm-opt@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + + '@webassemblyjs/wasm-parser@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-api-error': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wast-printer@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@xtuc/long': 4.2.2 + + '@xtuc/ieee754@1.2.0': {} + + '@xtuc/long@4.2.2': {} + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + acorn-import-attributes@1.9.5(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn-import-phases@1.0.4(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + optional: true + + acorn-jsx@5.3.2(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn-walk@8.3.5: + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + + address@1.2.2: {} + + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + + ajv-formats@2.1.1(ajv@8.18.0): + optionalDependencies: + ajv: 8.18.0 + + ajv-keywords@3.5.2(ajv@6.14.0): + dependencies: + ajv: 6.14.0 + + ajv-keywords@5.1.0(ajv@8.18.0): + dependencies: + ajv: 8.18.0 + fast-deep-equal: 3.1.3 + + ajv@6.14.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.18.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + algoliasearch-helper@3.28.1(algoliasearch@5.50.1): + dependencies: + '@algolia/events': 4.0.1 + algoliasearch: 5.50.1 + + algoliasearch@5.50.1: + dependencies: + '@algolia/abtesting': 1.16.1 + '@algolia/client-abtesting': 5.50.1 + '@algolia/client-analytics': 5.50.1 + '@algolia/client-common': 5.50.1 + '@algolia/client-insights': 5.50.1 + '@algolia/client-personalization': 5.50.1 + '@algolia/client-query-suggestions': 5.50.1 + '@algolia/client-search': 5.50.1 + '@algolia/ingestion': 1.50.1 + '@algolia/monitoring': 1.50.1 + '@algolia/recommend': 5.50.1 + '@algolia/requester-browser-xhr': 5.50.1 + '@algolia/requester-fetch': 5.50.1 + '@algolia/requester-node-http': 5.50.1 + + ansi-align@3.0.1: + dependencies: + string-width: 4.2.3 + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-html-community@0.0.8: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.3: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 + + arg@5.0.2: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + array-flatten@1.1.1: {} + + array-union@2.1.0: {} + + asn1js@3.0.7: + dependencies: + pvtsutils: 1.3.6 + pvutils: 1.1.5 + tslib: 2.8.1 + + astring@1.9.0: {} + + autoprefixer@10.4.27(postcss@8.5.9): + dependencies: + browserslist: 4.28.2 + caniuse-lite: 1.0.30001787 + fraction.js: 5.3.4 + picocolors: 1.1.1 + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + babel-loader@9.2.1(@babel/core@7.29.0)(webpack@5.95.0): + dependencies: + '@babel/core': 7.29.0 + find-cache-dir: 4.0.0 + schema-utils: 4.3.3 + webpack: 5.95.0 + + babel-plugin-dynamic-import-node@2.3.3: + dependencies: + object.assign: 4.1.7 + + babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.29.0): + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + core-js-compat: 3.49.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.14.2(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + core-js-compat: 3.49.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-regenerator@0.6.8(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + bail@2.0.2: {} + + balanced-match@1.0.2: {} + + baseline-browser-mapping@2.10.18: {} + + batch@0.6.1: {} + + big.js@5.2.2: {} + + binary-extensions@2.3.0: {} + + body-parser@1.20.4: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.14.2 + raw-body: 2.5.3 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + bonjour-service@1.3.0: + dependencies: + fast-deep-equal: 3.1.3 + multicast-dns: 7.2.5 + + boolbase@1.0.0: {} + + boxen@6.2.1: + dependencies: + ansi-align: 3.0.1 + camelcase: 6.3.0 + chalk: 4.1.2 + cli-boxes: 3.0.0 + string-width: 5.1.2 + type-fest: 2.19.0 + widest-line: 4.0.1 + wrap-ansi: 8.1.0 + + boxen@7.1.1: + dependencies: + ansi-align: 3.0.1 + camelcase: 7.0.1 + chalk: 5.6.2 + cli-boxes: 3.0.0 + string-width: 5.1.2 + type-fest: 2.19.0 + widest-line: 4.0.1 + wrap-ansi: 8.1.0 + + brace-expansion@1.1.14: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.28.2: + dependencies: + baseline-browser-mapping: 2.10.18 + caniuse-lite: 1.0.30001787 + electron-to-chromium: 1.5.335 + node-releases: 2.0.37 + update-browserslist-db: 1.2.3(browserslist@4.28.2) + + buffer-from@1.1.2: {} + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.1.0 + + bytes@3.0.0: {} + + bytes@3.1.2: {} + + bytestreamjs@2.0.1: {} + + cacheable-lookup@7.0.0: {} + + cacheable-request@10.2.14: + dependencies: + '@types/http-cache-semantics': 4.2.0 + get-stream: 6.0.1 + http-cache-semantics: 4.2.0 + keyv: 4.5.4 + mimic-response: 4.0.0 + normalize-url: 8.1.1 + responselike: 3.0.0 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.9: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + camel-case@4.1.2: + dependencies: + pascal-case: 3.1.2 + tslib: 2.8.1 + + camelcase@6.3.0: {} + + camelcase@7.0.1: {} + + caniuse-api@3.0.0: + dependencies: + browserslist: 4.28.2 + caniuse-lite: 1.0.30001787 + lodash.memoize: 4.1.2 + lodash.uniq: 4.5.0 + + caniuse-lite@1.0.30001787: {} + + ccount@2.0.1: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.6.2: {} + + char-regex@1.0.2: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.2.2 + css-what: 6.2.2 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + + cheerio@1.0.0-rc.12: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.2.2 + htmlparser2: 8.0.2 + parse5: 7.3.0 + parse5-htmlparser2-tree-adapter: 7.1.0 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chrome-trace-event@1.0.4: {} + + ci-info@3.9.0: {} + + clean-css@5.3.3: + dependencies: + source-map: 0.6.1 + + clean-stack@2.2.0: {} + + cli-boxes@3.0.0: {} + + cli-table3@0.6.5: + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + + clone-deep@4.0.1: + dependencies: + is-plain-object: 2.0.4 + kind-of: 6.0.3 + shallow-clone: 3.0.1 + + clsx@2.1.1: {} + + collapse-white-space@2.1.0: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + colord@2.9.3: {} + + colorette@2.0.20: {} + + combine-promises@1.2.0: {} + + comma-separated-tokens@2.0.3: {} + + commander@10.0.1: {} + + commander@2.20.3: {} + + commander@5.1.0: {} + + commander@7.2.0: {} + + commander@8.3.0: {} + + common-path-prefix@3.0.0: {} + + compressible@2.0.18: + dependencies: + mime-db: 1.54.0 + + compression@1.8.1: + dependencies: + bytes: 3.1.2 + compressible: 2.0.18 + debug: 2.6.9 + negotiator: 0.6.4 + on-headers: 1.1.0 + safe-buffer: 5.2.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + concat-map@0.0.1: {} + + config-chain@1.1.13: + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + + configstore@6.0.0: + dependencies: + dot-prop: 6.0.1 + graceful-fs: 4.2.11 + unique-string: 3.0.0 + write-file-atomic: 3.0.3 + xdg-basedir: 5.1.0 + + connect-history-api-fallback@2.0.0: {} + + consola@3.4.2: {} + + content-disposition@0.5.2: {} + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + convert-source-map@2.0.0: {} + + cookie-signature@1.0.7: {} + + cookie@0.7.2: {} + + copy-webpack-plugin@11.0.0(webpack@5.95.0): + dependencies: + fast-glob: 3.3.3 + glob-parent: 6.0.2 + globby: 13.2.2 + normalize-path: 3.0.0 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + webpack: 5.95.0 + + core-js-compat@3.49.0: + dependencies: + browserslist: 4.28.2 + + core-js-pure@3.49.0: {} + + core-js@3.49.0: {} + + core-util-is@1.0.3: {} + + cosmiconfig@8.3.6(typescript@5.9.3): + dependencies: + import-fresh: 3.3.1 + js-yaml: 4.1.1 + parse-json: 5.2.0 + path-type: 4.0.0 + optionalDependencies: + typescript: 5.9.3 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crypto-random-string@4.0.0: + dependencies: + type-fest: 1.4.0 + + css-blank-pseudo@7.0.1(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + css-declaration-sorter@7.4.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + css-has-pseudo@7.0.3(postcss@8.5.9): + dependencies: + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1) + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + postcss-value-parser: 4.2.0 + + css-loader@6.11.0(webpack@5.95.0): + dependencies: + icss-utils: 5.1.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.9) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.9) + postcss-modules-scope: 3.2.1(postcss@8.5.9) + postcss-modules-values: 4.0.0(postcss@8.5.9) + postcss-value-parser: 4.2.0 + semver: 7.7.4 + optionalDependencies: + webpack: 5.95.0 + + css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(webpack@5.95.0): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + cssnano: 6.1.2(postcss@8.5.9) + jest-worker: 29.7.0 + postcss: 8.5.9 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + webpack: 5.95.0 + optionalDependencies: + clean-css: 5.3.3 + + css-prefers-color-scheme@10.0.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + css-select@4.3.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 4.3.1 + domutils: 2.8.0 + nth-check: 2.1.1 + + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-tree@2.2.1: + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.1 + + css-tree@2.3.1: + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.2.1 + + css-what@6.2.2: {} + + cssdb@8.8.0: {} + + cssesc@3.0.0: {} + + cssnano-preset-advanced@6.1.2(postcss@8.5.9): + dependencies: + autoprefixer: 10.4.27(postcss@8.5.9) + browserslist: 4.28.2 + cssnano-preset-default: 6.1.2(postcss@8.5.9) + postcss: 8.5.9 + postcss-discard-unused: 6.0.5(postcss@8.5.9) + postcss-merge-idents: 6.0.3(postcss@8.5.9) + postcss-reduce-idents: 6.0.3(postcss@8.5.9) + postcss-zindex: 6.0.2(postcss@8.5.9) + + cssnano-preset-default@6.1.2(postcss@8.5.9): + dependencies: + browserslist: 4.28.2 + css-declaration-sorter: 7.4.0(postcss@8.5.9) + cssnano-utils: 4.0.2(postcss@8.5.9) + postcss: 8.5.9 + postcss-calc: 9.0.1(postcss@8.5.9) + postcss-colormin: 6.1.0(postcss@8.5.9) + postcss-convert-values: 6.1.0(postcss@8.5.9) + postcss-discard-comments: 6.0.2(postcss@8.5.9) + postcss-discard-duplicates: 6.0.3(postcss@8.5.9) + postcss-discard-empty: 6.0.3(postcss@8.5.9) + postcss-discard-overridden: 6.0.2(postcss@8.5.9) + postcss-merge-longhand: 6.0.5(postcss@8.5.9) + postcss-merge-rules: 6.1.1(postcss@8.5.9) + postcss-minify-font-values: 6.1.0(postcss@8.5.9) + postcss-minify-gradients: 6.0.3(postcss@8.5.9) + postcss-minify-params: 6.1.0(postcss@8.5.9) + postcss-minify-selectors: 6.0.4(postcss@8.5.9) + postcss-normalize-charset: 6.0.2(postcss@8.5.9) + postcss-normalize-display-values: 6.0.2(postcss@8.5.9) + postcss-normalize-positions: 6.0.2(postcss@8.5.9) + postcss-normalize-repeat-style: 6.0.2(postcss@8.5.9) + postcss-normalize-string: 6.0.2(postcss@8.5.9) + postcss-normalize-timing-functions: 6.0.2(postcss@8.5.9) + postcss-normalize-unicode: 6.1.0(postcss@8.5.9) + postcss-normalize-url: 6.0.2(postcss@8.5.9) + postcss-normalize-whitespace: 6.0.2(postcss@8.5.9) + postcss-ordered-values: 6.0.2(postcss@8.5.9) + postcss-reduce-initial: 6.1.0(postcss@8.5.9) + postcss-reduce-transforms: 6.0.2(postcss@8.5.9) + postcss-svgo: 6.0.3(postcss@8.5.9) + postcss-unique-selectors: 6.0.4(postcss@8.5.9) + + cssnano-utils@4.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + cssnano@6.1.2(postcss@8.5.9): + dependencies: + cssnano-preset-default: 6.1.2(postcss@8.5.9) + lilconfig: 3.1.3 + postcss: 8.5.9 + + csso@5.0.5: + dependencies: + css-tree: 2.2.1 + + csstype@3.2.3: {} + + debounce@1.2.1: {} + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + + deep-extend@0.6.0: {} + + deepmerge@4.3.1: {} + + default-browser-id@5.0.1: {} + + default-browser@5.5.0: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.1 + + defer-to-connect@2.0.1: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-lazy-prop@2.0.0: {} + + define-lazy-prop@3.0.0: {} + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + depd@1.1.2: {} + + depd@2.0.0: {} + + dequal@2.0.3: {} + + destroy@1.2.0: {} + + detect-node@2.1.0: {} + + detect-port@1.6.1: + dependencies: + address: 1.2.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dns-packet@5.6.1: + dependencies: + '@leichtgewicht/ip-codec': 2.0.5 + + dom-converter@0.2.0: + dependencies: + utila: 0.4.0 + + dom-serializer@1.4.1: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + entities: 2.2.0 + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@4.3.1: + dependencies: + domelementtype: 2.3.0 + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@2.8.0: + dependencies: + dom-serializer: 1.4.1 + domelementtype: 2.3.0 + domhandler: 4.3.1 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dot-case@3.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.8.1 + + dot-prop@6.0.1: + dependencies: + is-obj: 2.0.0 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + duplexer@0.1.2: {} + + eastasianwidth@0.2.0: {} + + ee-first@1.1.1: {} + + electron-to-chromium@1.5.335: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + emojilib@2.4.0: {} + + emojis-list@3.0.0: {} + + emoticon@4.1.0: {} + + encodeurl@2.0.0: {} + + enhanced-resolve@5.20.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.2 + + entities@2.2.0: {} + + entities@4.5.0: {} + + entities@6.0.1: {} + + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-module-lexer@1.7.0: {} + + es-module-lexer@2.0.0: + optional: true + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + esast-util-from-estree@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + unist-util-position-from-estree: 2.0.0 + + esast-util-from-js@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + acorn: 8.16.0 + esast-util-from-estree: 2.0.0 + vfile-message: 4.0.3 + + escalade@3.2.0: {} + + escape-goat@4.0.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + escape-string-regexp@5.0.0: {} + + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + esprima@4.0.1: {} + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + estree-util-attach-comments@3.0.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-build-jsx@3.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-walker: 3.0.3 + + estree-util-is-identifier-name@3.0.0: {} + + estree-util-scope@1.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + + estree-util-to-js@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + astring: 1.9.0 + source-map: 0.7.6 + + estree-util-value-to-estree@3.5.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-visit@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/unist': 3.0.3 + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + esutils@2.0.3: {} + + eta@2.2.0: {} + + etag@1.8.1: {} + + eval@0.1.8: + dependencies: + '@types/node': 25.6.0 + require-like: 0.1.2 + + eventemitter3@4.0.7: {} + + events@3.3.0: {} + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + express@4.22.1: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.4 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.0.7 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.2 + fresh: 0.5.2 + http-errors: 2.0.1 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.13 + proxy-addr: 2.0.7 + qs: 6.14.2 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.2 + serve-static: 1.16.3 + setprototypeof: 1.2.0 + statuses: 2.0.2 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend@3.0.2: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-uri@3.1.0: {} + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fault@2.0.1: + dependencies: + format: 0.2.2 + + faye-websocket@0.11.4: + dependencies: + websocket-driver: 0.7.4 + + feed@4.2.2: + dependencies: + xml-js: 1.6.11 + + figures@3.2.0: + dependencies: + escape-string-regexp: 1.0.5 + + file-loader@6.2.0(webpack@5.106.1): + dependencies: + loader-utils: 2.0.4 + schema-utils: 3.3.0 + webpack: 5.106.1 + optional: true + + file-loader@6.2.0(webpack@5.95.0): + dependencies: + loader-utils: 2.0.4 + schema-utils: 3.3.0 + webpack: 5.95.0 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@1.3.2: + dependencies: + debug: 2.6.9 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + find-cache-dir@4.0.0: + dependencies: + common-path-prefix: 3.0.0 + pkg-dir: 7.0.0 + + find-up@6.3.0: + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + + flat@5.0.2: {} + + follow-redirects@1.15.11: {} + + form-data-encoder@2.1.4: {} + + format@0.2.2: {} + + forwarded@0.2.0: {} + + fraction.js@5.3.4: {} + + fresh@0.5.2: {} + + fs-extra@11.3.4: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gensync@1.0.0-beta.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-own-enumerable-property-symbols@3.0.2: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stream@6.0.1: {} + + github-slugger@1.5.0: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob-to-regex.js@1.2.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + + glob-to-regexp@0.4.1: {} + + global-dirs@3.0.1: + dependencies: + ini: 2.0.0 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + globby@13.2.2: + dependencies: + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 4.0.0 + + gopd@1.2.0: {} + + got@12.6.1: + dependencies: + '@sindresorhus/is': 5.6.0 + '@szmarczak/http-timer': 5.0.1 + cacheable-lookup: 7.0.0 + cacheable-request: 10.2.14 + decompress-response: 6.0.0 + form-data-encoder: 2.1.4 + get-stream: 6.0.1 + http2-wrapper: 2.2.1 + lowercase-keys: 3.0.0 + p-cancelable: 3.0.0 + responselike: 3.0.0 + + graceful-fs@4.2.10: {} + + graceful-fs@4.2.11: {} + + gray-matter@4.0.3: + dependencies: + js-yaml: 3.14.2 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 + + gzip-size@6.0.0: + dependencies: + duplexer: 0.1.2 + + handle-thing@2.0.1: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbols@1.1.0: {} + + has-yarn@3.0.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hast-util-from-parse5@8.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + devlop: 1.1.0 + hastscript: 9.0.1 + property-information: 7.1.0 + vfile: 6.0.3 + vfile-location: 5.0.3 + web-namespaces: 2.0.1 + + hast-util-parse-selector@4.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-raw@9.1.0: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + '@ungap/structured-clone': 1.3.0 + hast-util-from-parse5: 8.0.3 + hast-util-to-parse5: 8.0.1 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + parse5: 7.3.0 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-to-estree@3.1.3: + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-attach-comments: 3.0.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + hast-util-to-parse5@8.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hastscript@9.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + + he@1.2.0: {} + + history@4.10.1: + dependencies: + '@babel/runtime': 7.29.2 + loose-envify: 1.4.0 + resolve-pathname: 3.0.0 + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 + value-equal: 1.0.1 + + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + + hpack.js@2.1.6: + dependencies: + inherits: 2.0.4 + obuf: 1.1.2 + readable-stream: 2.3.8 + wbuf: 1.7.3 + + html-escaper@2.0.2: {} + + html-minifier-terser@6.1.0: + dependencies: + camel-case: 4.1.2 + clean-css: 5.3.3 + commander: 8.3.0 + he: 1.2.0 + param-case: 3.0.4 + relateurl: 0.2.7 + terser: 5.46.1 + + html-minifier-terser@7.2.0: + dependencies: + camel-case: 4.1.2 + clean-css: 5.3.3 + commander: 10.0.1 + entities: 4.5.0 + param-case: 3.0.4 + relateurl: 0.2.7 + terser: 5.46.1 + + html-tags@3.3.1: {} + + html-void-elements@3.0.0: {} + + html-webpack-plugin@5.6.6(webpack@5.95.0): + dependencies: + '@types/html-minifier-terser': 6.1.0 + html-minifier-terser: 6.1.0 + lodash: 4.18.1 + pretty-error: 4.0.0 + tapable: 2.3.2 + optionalDependencies: + webpack: 5.95.0 + + htmlparser2@6.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + domutils: 2.8.0 + entities: 2.2.0 + + htmlparser2@8.0.2: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 4.5.0 + + http-cache-semantics@4.2.0: {} + + http-deceiver@1.2.7: {} + + http-errors@1.8.1: + dependencies: + depd: 1.1.2 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 1.5.0 + toidentifier: 1.0.1 + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + http-parser-js@0.5.10: {} + + http-proxy-middleware@2.0.9(@types/express@4.17.25): + dependencies: + '@types/http-proxy': 1.17.17 + http-proxy: 1.18.1 + is-glob: 4.0.3 + is-plain-obj: 3.0.0 + micromatch: 4.0.8 + optionalDependencies: + '@types/express': 4.17.25 + transitivePeerDependencies: + - debug + + http-proxy@1.18.1: + dependencies: + eventemitter3: 4.0.7 + follow-redirects: 1.15.11 + requires-port: 1.0.0 + transitivePeerDependencies: + - debug + + http2-wrapper@2.2.1: + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + + human-signals@2.1.0: {} + + hyperdyperid@1.2.0: {} + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + icss-utils@5.1.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + ignore@5.3.2: {} + + image-size@2.0.2: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-lazy@4.0.0: {} + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + infima@0.2.0-alpha.45: {} + + inherits@2.0.4: {} + + ini@1.3.8: {} + + ini@2.0.0: {} + + inline-style-parser@0.2.7: {} + + invariant@2.2.4: + dependencies: + loose-envify: 1.4.0 + + ipaddr.js@1.9.1: {} + + ipaddr.js@2.3.0: {} + + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-arrayish@0.2.1: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-ci@3.0.1: + dependencies: + ci-info: 3.9.0 + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-decimal@2.0.1: {} + + is-docker@2.2.1: {} + + is-docker@3.0.0: {} + + is-extendable@0.1.1: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hexadecimal@2.0.1: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-installed-globally@0.4.0: + dependencies: + global-dirs: 3.0.1 + is-path-inside: 3.0.3 + + is-network-error@1.3.1: {} + + is-npm@6.1.0: {} + + is-number@7.0.0: {} + + is-obj@1.0.1: {} + + is-obj@2.0.0: {} + + is-path-inside@3.0.3: {} + + is-plain-obj@3.0.0: {} + + is-plain-obj@4.1.0: {} + + is-plain-object@2.0.4: + dependencies: + isobject: 3.0.1 + + is-regexp@1.0.0: {} + + is-stream@2.0.1: {} + + is-typedarray@1.0.0: {} + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + is-wsl@3.1.1: + dependencies: + is-inside-container: 1.0.0 + + is-yarn-global@0.4.1: {} + + isarray@0.0.1: {} + + isarray@1.0.0: {} + + isexe@2.0.0: {} + + isobject@3.0.1: {} + + jest-util@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 25.6.0 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.2 + + jest-worker@27.5.1: + dependencies: + '@types/node': 25.6.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest-worker@29.7.0: + dependencies: + '@types/node': 25.6.0 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jiti@1.21.7: {} + + joi@17.13.3: + dependencies: + '@hapi/hoek': 9.3.0 + '@hapi/topo': 5.1.0 + '@sideway/address': 4.1.5 + '@sideway/formula': 3.0.1 + '@sideway/pinpoint': 2.0.0 + + js-tokens@4.0.0: {} + + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-parse-even-better-errors@2.3.1: {} + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json5@2.2.3: {} + + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kind-of@6.0.3: {} + + kleur@3.0.3: {} + + latest-version@7.0.0: + dependencies: + package-json: 8.1.1 + + launch-editor@2.13.2: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.8.3 + + leven@3.1.0: {} + + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + loader-runner@4.3.1: {} + + loader-utils@2.0.4: + dependencies: + big.js: 5.2.2 + emojis-list: 3.0.0 + json5: 2.2.3 + + locate-path@7.2.0: + dependencies: + p-locate: 6.0.0 + + lodash.debounce@4.0.8: {} + + lodash.memoize@4.1.2: {} + + lodash.uniq@4.5.0: {} + + lodash@4.18.1: {} + + longest-streak@3.1.0: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lower-case@2.0.2: + dependencies: + tslib: 2.8.1 + + lowercase-keys@3.0.0: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + markdown-extensions@2.0.0: {} + + markdown-table@2.0.0: + dependencies: + repeat-string: 1.6.1 + + markdown-table@3.0.4: {} + + math-intrinsics@1.1.0: {} + + mdast-util-directive@3.1.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-visit-parents: 6.0.2 + transitivePeerDependencies: + - supports-color + + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.0.3: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-frontmatter@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + escape-string-regexp: 5.0.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + micromark-extension-frontmatter: 2.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.3 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.3 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-hast@13.2.1: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + mdn-data@2.0.28: {} + + mdn-data@2.0.30: {} + + media-typer@0.3.0: {} + + memfs@4.57.1(tslib@2.8.1): + dependencies: + '@jsonjoy.com/fs-core': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-to-fsa': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + glob-to-regex.js: 1.2.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + merge-descriptors@1.0.3: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + methods@1.1.2: {} + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-directive@3.0.2: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + parse-entities: 4.0.2 + + micromark-extension-frontmatter@2.0.0: + dependencies: + fault: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-expression@3.0.1: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-jsx@3.0.2: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-extension-mdx-md@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-mdxjs-esm@3.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-extension-mdxjs@3.0.0: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + micromark-extension-mdx-expression: 3.0.1 + micromark-extension-mdx-jsx: 3.0.2 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-mdx-expression@2.0.3: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-factory-space@1.1.0: + dependencies: + micromark-util-character: 1.2.0 + micromark-util-types: 1.1.0 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@1.2.0: + dependencies: + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-events-to-acorn@2.0.3: + dependencies: + '@types/estree': 1.0.8 + '@types/unist': 3.0.3 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@1.1.0: {} + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@1.1.0: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + + mime-db@1.33.0: {} + + mime-db@1.52.0: {} + + mime-db@1.54.0: {} + + mime-types@2.1.18: + dependencies: + mime-db: 1.33.0 + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + + mime@1.6.0: {} + + mimic-fn@2.1.0: {} + + mimic-response@3.1.0: {} + + mimic-response@4.0.0: {} + + mini-css-extract-plugin@2.10.2(webpack@5.95.0): + dependencies: + schema-utils: 4.3.3 + tapable: 2.3.2 + webpack: 5.95.0 + + minimalistic-assert@1.0.1: {} + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.14 + + minimist@1.2.8: {} + + mrmime@2.0.1: {} + + ms@2.0.0: {} + + ms@2.1.3: {} + + multicast-dns@7.2.5: + dependencies: + dns-packet: 5.6.1 + thunky: 1.1.0 + + nanoid@3.3.11: {} + + negotiator@0.6.3: {} + + negotiator@0.6.4: {} + + neo-async@2.6.2: {} + + no-case@3.0.4: + dependencies: + lower-case: 2.0.2 + tslib: 2.8.1 + + node-emoji@2.2.0: + dependencies: + '@sindresorhus/is': 4.6.0 + char-regex: 1.0.2 + emojilib: 2.4.0 + skin-tone: 2.0.0 + + node-releases@2.0.37: {} + + normalize-path@3.0.0: {} + + normalize-url@8.1.1: {} + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + nprogress@0.2.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + null-loader@4.0.1(webpack@5.95.0): + dependencies: + loader-utils: 2.0.4 + schema-utils: 3.3.0 + webpack: 5.95.0 + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + obuf@1.1.2: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + on-headers@1.1.0: {} + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + open@10.2.0: + dependencies: + default-browser: 5.5.0 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + wsl-utils: 0.1.0 + + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + + opener@1.5.2: {} + + p-cancelable@3.0.0: {} + + p-finally@1.0.0: {} + + p-limit@4.0.0: + dependencies: + yocto-queue: 1.2.2 + + p-locate@6.0.0: + dependencies: + p-limit: 4.0.0 + + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 + + p-queue@6.6.2: + dependencies: + eventemitter3: 4.0.7 + p-timeout: 3.2.0 + + p-retry@6.2.1: + dependencies: + '@types/retry': 0.12.2 + is-network-error: 1.3.1 + retry: 0.13.1 + + p-timeout@3.2.0: + dependencies: + p-finally: 1.0.0 + + package-json@8.1.1: + dependencies: + got: 12.6.1 + registry-auth-token: 5.1.1 + registry-url: 6.0.1 + semver: 7.7.4 + + param-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.8.1 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.3.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.29.0 + error-ex: 1.3.4 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + parse-numeric-range@1.3.0: {} + + parse5-htmlparser2-tree-adapter@7.1.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.3.0 + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + + parseurl@1.3.3: {} + + pascal-case@3.1.2: + dependencies: + no-case: 3.0.4 + tslib: 2.8.1 + + path-exists@5.0.0: {} + + path-is-inside@1.0.2: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-to-regexp@0.1.13: {} + + path-to-regexp@1.9.0: + dependencies: + isarray: 0.0.1 + + path-to-regexp@3.3.0: {} + + path-type@4.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.2: {} + + pkg-dir@7.0.0: + dependencies: + find-up: 6.3.0 + + pkijs@3.4.0: + dependencies: + '@noble/hashes': 1.4.0 + asn1js: 3.0.7 + bytestreamjs: 2.0.1 + pvtsutils: 1.3.6 + pvutils: 1.1.5 + tslib: 2.8.1 + + postcss-attribute-case-insensitive@7.0.1(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + postcss-calc@9.0.1(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 6.1.2 + postcss-value-parser: 4.2.0 + + postcss-clamp@4.1.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-color-functional-notation@7.0.12(postcss@8.5.9): + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + postcss-color-hex-alpha@10.0.0(postcss@8.5.9): + dependencies: + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-color-rebeccapurple@10.0.0(postcss@8.5.9): + dependencies: + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-colormin@6.1.0(postcss@8.5.9): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + colord: 2.9.3 + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-convert-values@6.1.0(postcss@8.5.9): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-custom-media@11.0.6(postcss@8.5.9): + dependencies: + '@csstools/cascade-layer-name-parser': 2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/media-query-list-parser': 4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + postcss: 8.5.9 + + postcss-custom-properties@14.0.6(postcss@8.5.9): + dependencies: + '@csstools/cascade-layer-name-parser': 2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-custom-selectors@8.0.5(postcss@8.5.9): + dependencies: + '@csstools/cascade-layer-name-parser': 2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + postcss-dir-pseudo-class@9.0.1(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + postcss-discard-comments@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-discard-duplicates@6.0.3(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-discard-empty@6.0.3(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-discard-overridden@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-discard-unused@6.0.5(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 6.1.2 + + postcss-double-position-gradients@6.0.4(postcss@8.5.9): + dependencies: + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-focus-visible@10.0.1(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + postcss-focus-within@9.0.1(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + postcss-font-variant@5.0.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-gap-properties@6.0.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-image-set-function@7.0.0(postcss@8.5.9): + dependencies: + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-lab-function@7.0.12(postcss@8.5.9): + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/utilities': 2.0.0(postcss@8.5.9) + postcss: 8.5.9 + + postcss-loader@7.3.4(postcss@8.5.9)(typescript@5.9.3)(webpack@5.95.0): + dependencies: + cosmiconfig: 8.3.6(typescript@5.9.3) + jiti: 1.21.7 + postcss: 8.5.9 + semver: 7.7.4 + webpack: 5.95.0 + transitivePeerDependencies: + - typescript + + postcss-logical@8.1.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-merge-idents@6.0.3(postcss@8.5.9): + dependencies: + cssnano-utils: 4.0.2(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-merge-longhand@6.0.5(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + stylehacks: 6.1.1(postcss@8.5.9) + + postcss-merge-rules@6.1.1(postcss@8.5.9): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + cssnano-utils: 4.0.2(postcss@8.5.9) + postcss: 8.5.9 + postcss-selector-parser: 6.1.2 + + postcss-minify-font-values@6.1.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-minify-gradients@6.0.3(postcss@8.5.9): + dependencies: + colord: 2.9.3 + cssnano-utils: 4.0.2(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-minify-params@6.1.0(postcss@8.5.9): + dependencies: + browserslist: 4.28.2 + cssnano-utils: 4.0.2(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-minify-selectors@6.0.4(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 6.1.2 + + postcss-modules-extract-imports@3.1.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-modules-local-by-default@4.2.0(postcss@8.5.9): + dependencies: + icss-utils: 5.1.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + postcss-value-parser: 4.2.0 + + postcss-modules-scope@3.2.1(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + postcss-modules-values@4.0.0(postcss@8.5.9): + dependencies: + icss-utils: 5.1.0(postcss@8.5.9) + postcss: 8.5.9 + + postcss-nesting@13.0.2(postcss@8.5.9): + dependencies: + '@csstools/selector-resolve-nested': 3.1.0(postcss-selector-parser@7.1.1) + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1) + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + postcss-normalize-charset@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-normalize-display-values@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-normalize-positions@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-normalize-repeat-style@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-normalize-string@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-normalize-timing-functions@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-normalize-unicode@6.1.0(postcss@8.5.9): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-normalize-url@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-normalize-whitespace@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-opacity-percentage@3.0.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-ordered-values@6.0.2(postcss@8.5.9): + dependencies: + cssnano-utils: 4.0.2(postcss@8.5.9) + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-overflow-shorthand@6.0.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-page-break@3.0.4(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-place@10.0.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-preset-env@10.6.1(postcss@8.5.9): + dependencies: + '@csstools/postcss-alpha-function': 1.0.1(postcss@8.5.9) + '@csstools/postcss-cascade-layers': 5.0.2(postcss@8.5.9) + '@csstools/postcss-color-function': 4.0.12(postcss@8.5.9) + '@csstools/postcss-color-function-display-p3-linear': 1.0.1(postcss@8.5.9) + '@csstools/postcss-color-mix-function': 3.0.12(postcss@8.5.9) + '@csstools/postcss-color-mix-variadic-function-arguments': 1.0.2(postcss@8.5.9) + '@csstools/postcss-content-alt-text': 2.0.8(postcss@8.5.9) + '@csstools/postcss-contrast-color-function': 2.0.12(postcss@8.5.9) + '@csstools/postcss-exponential-functions': 2.0.9(postcss@8.5.9) + '@csstools/postcss-font-format-keywords': 4.0.0(postcss@8.5.9) + '@csstools/postcss-gamut-mapping': 2.0.11(postcss@8.5.9) + '@csstools/postcss-gradients-interpolation-method': 5.0.12(postcss@8.5.9) + '@csstools/postcss-hwb-function': 4.0.12(postcss@8.5.9) + '@csstools/postcss-ic-unit': 4.0.4(postcss@8.5.9) + '@csstools/postcss-initial': 2.0.1(postcss@8.5.9) + '@csstools/postcss-is-pseudo-class': 5.0.3(postcss@8.5.9) + '@csstools/postcss-light-dark-function': 2.0.11(postcss@8.5.9) + '@csstools/postcss-logical-float-and-clear': 3.0.0(postcss@8.5.9) + '@csstools/postcss-logical-overflow': 2.0.0(postcss@8.5.9) + '@csstools/postcss-logical-overscroll-behavior': 2.0.0(postcss@8.5.9) + '@csstools/postcss-logical-resize': 3.0.0(postcss@8.5.9) + '@csstools/postcss-logical-viewport-units': 3.0.4(postcss@8.5.9) + '@csstools/postcss-media-minmax': 2.0.9(postcss@8.5.9) + '@csstools/postcss-media-queries-aspect-ratio-number-values': 3.0.5(postcss@8.5.9) + '@csstools/postcss-nested-calc': 4.0.0(postcss@8.5.9) + '@csstools/postcss-normalize-display-values': 4.0.1(postcss@8.5.9) + '@csstools/postcss-oklab-function': 4.0.12(postcss@8.5.9) + '@csstools/postcss-position-area-property': 1.0.0(postcss@8.5.9) + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.9) + '@csstools/postcss-property-rule-prelude-list': 1.0.0(postcss@8.5.9) + '@csstools/postcss-random-function': 2.0.1(postcss@8.5.9) + '@csstools/postcss-relative-color-syntax': 3.0.12(postcss@8.5.9) + '@csstools/postcss-scope-pseudo-class': 4.0.1(postcss@8.5.9) + '@csstools/postcss-sign-functions': 1.1.4(postcss@8.5.9) + '@csstools/postcss-stepped-value-functions': 4.0.9(postcss@8.5.9) + '@csstools/postcss-syntax-descriptor-syntax-production': 1.0.1(postcss@8.5.9) + '@csstools/postcss-system-ui-font-family': 1.0.0(postcss@8.5.9) + '@csstools/postcss-text-decoration-shorthand': 4.0.3(postcss@8.5.9) + '@csstools/postcss-trigonometric-functions': 4.0.9(postcss@8.5.9) + '@csstools/postcss-unset-value': 4.0.0(postcss@8.5.9) + autoprefixer: 10.4.27(postcss@8.5.9) + browserslist: 4.28.2 + css-blank-pseudo: 7.0.1(postcss@8.5.9) + css-has-pseudo: 7.0.3(postcss@8.5.9) + css-prefers-color-scheme: 10.0.0(postcss@8.5.9) + cssdb: 8.8.0 + postcss: 8.5.9 + postcss-attribute-case-insensitive: 7.0.1(postcss@8.5.9) + postcss-clamp: 4.1.0(postcss@8.5.9) + postcss-color-functional-notation: 7.0.12(postcss@8.5.9) + postcss-color-hex-alpha: 10.0.0(postcss@8.5.9) + postcss-color-rebeccapurple: 10.0.0(postcss@8.5.9) + postcss-custom-media: 11.0.6(postcss@8.5.9) + postcss-custom-properties: 14.0.6(postcss@8.5.9) + postcss-custom-selectors: 8.0.5(postcss@8.5.9) + postcss-dir-pseudo-class: 9.0.1(postcss@8.5.9) + postcss-double-position-gradients: 6.0.4(postcss@8.5.9) + postcss-focus-visible: 10.0.1(postcss@8.5.9) + postcss-focus-within: 9.0.1(postcss@8.5.9) + postcss-font-variant: 5.0.0(postcss@8.5.9) + postcss-gap-properties: 6.0.0(postcss@8.5.9) + postcss-image-set-function: 7.0.0(postcss@8.5.9) + postcss-lab-function: 7.0.12(postcss@8.5.9) + postcss-logical: 8.1.0(postcss@8.5.9) + postcss-nesting: 13.0.2(postcss@8.5.9) + postcss-opacity-percentage: 3.0.0(postcss@8.5.9) + postcss-overflow-shorthand: 6.0.0(postcss@8.5.9) + postcss-page-break: 3.0.4(postcss@8.5.9) + postcss-place: 10.0.0(postcss@8.5.9) + postcss-pseudo-class-any-link: 10.0.1(postcss@8.5.9) + postcss-replace-overflow-wrap: 4.0.0(postcss@8.5.9) + postcss-selector-not: 8.0.1(postcss@8.5.9) + + postcss-pseudo-class-any-link@10.0.1(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + postcss-reduce-idents@6.0.3(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-reduce-initial@6.1.0(postcss@8.5.9): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + postcss: 8.5.9 + + postcss-reduce-transforms@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + + postcss-replace-overflow-wrap@4.0.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss-selector-not@8.0.1(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-selector-parser@7.1.1: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-sort-media-queries@5.2.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + sort-css-media-queries: 2.2.0 + + postcss-svgo@6.0.3(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-value-parser: 4.2.0 + svgo: 3.3.3 + + postcss-unique-selectors@6.0.4(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + postcss-selector-parser: 6.1.2 + + postcss-value-parser@4.2.0: {} + + postcss-zindex@6.0.2(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + postcss@8.5.9: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + pretty-error@4.0.0: + dependencies: + lodash: 4.18.1 + renderkid: 3.0.0 + + pretty-time@1.1.0: {} + + prism-react-renderer@2.4.1(react@18.3.1): + dependencies: + '@types/prismjs': 1.26.6 + clsx: 2.1.1 + react: 18.3.1 + + prismjs@1.30.0: {} + + process-nextick-args@2.0.1: {} + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + property-information@7.1.0: {} + + proto-list@1.2.4: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + punycode@2.3.1: {} + + pupa@3.3.0: + dependencies: + escape-goat: 4.0.0 + + pvtsutils@1.3.6: + dependencies: + tslib: 2.8.1 + + pvutils@1.1.5: {} + + qs@6.14.2: + dependencies: + side-channel: 1.1.0 + + queue-microtask@1.2.3: {} + + quick-lru@5.1.1: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + range-parser@1.2.0: {} + + range-parser@1.2.1: {} + + raw-body@2.5.3: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react-fast-compare@3.2.2: {} + + react-is@16.13.1: {} + + react-json-view-lite@2.5.0(react@18.3.1): + dependencies: + react: 18.3.1 + + react-loadable-ssr-addon-v5-slorber@1.0.3(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.95.0): + dependencies: + '@babel/runtime': 7.29.2 + react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' + webpack: 5.95.0 + + react-router-config@5.1.1(react-router@5.3.4(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + react: 18.3.1 + react-router: 5.3.4(react@18.3.1) + + react-router-dom@5.3.4(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + history: 4.10.1 + loose-envify: 1.4.0 + prop-types: 15.8.1 + react: 18.3.1 + react-router: 5.3.4(react@18.3.1) + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 + + react-router@5.3.4(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + history: 4.10.1 + hoist-non-react-statics: 3.3.2 + loose-envify: 1.4.0 + path-to-regexp: 1.9.0 + prop-types: 15.8.1 + react: 18.3.1 + react-is: 16.13.1 + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.2 + + recma-build-jsx@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-build-jsx: 3.0.1 + vfile: 6.0.3 + + recma-jsx@1.0.1(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + estree-util-to-js: 2.0.0 + recma-parse: 1.0.0 + recma-stringify: 1.0.0 + unified: 11.0.5 + + recma-parse@1.0.0: + dependencies: + '@types/estree': 1.0.8 + esast-util-from-js: 2.0.1 + unified: 11.0.5 + vfile: 6.0.3 + + recma-stringify@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-to-js: 2.0.0 + unified: 11.0.5 + vfile: 6.0.3 + + reflect-metadata@0.2.2: {} + + regenerate-unicode-properties@10.2.2: + dependencies: + regenerate: 1.4.2 + + regenerate@1.4.2: {} + + regexpu-core@6.4.0: + dependencies: + regenerate: 1.4.2 + regenerate-unicode-properties: 10.2.2 + regjsgen: 0.8.0 + regjsparser: 0.13.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.2.1 + + registry-auth-token@5.1.1: + dependencies: + '@pnpm/npm-conf': 3.0.2 + + registry-url@6.0.1: + dependencies: + rc: 1.2.8 + + regjsgen@0.8.0: {} + + regjsparser@0.13.1: + dependencies: + jsesc: 3.1.0 + + rehype-raw@7.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-raw: 9.1.0 + vfile: 6.0.3 + + rehype-recma@1.0.0: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + hast-util-to-estree: 3.1.3 + transitivePeerDependencies: + - supports-color + + relateurl@0.2.7: {} + + remark-directive@3.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-directive: 3.1.0 + micromark-extension-directive: 3.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-emoji@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + emoticon: 4.1.0 + mdast-util-find-and-replace: 3.0.2 + node-emoji: 2.2.0 + unified: 11.0.5 + + remark-frontmatter@5.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-frontmatter: 2.0.1 + micromark-extension-frontmatter: 2.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-mdx@3.1.1: + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.1 + unified: 11.0.5 + vfile: 6.0.3 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + + renderkid@3.0.0: + dependencies: + css-select: 4.3.0 + dom-converter: 0.2.0 + htmlparser2: 6.1.0 + lodash: 4.18.1 + strip-ansi: 6.0.1 + + repeat-string@1.6.1: {} + + require-from-string@2.0.2: {} + + require-like@0.1.2: {} + + requires-port@1.0.0: {} + + resolve-alpn@1.2.1: {} + + resolve-from@4.0.0: {} + + resolve-pathname@3.0.0: {} + + resolve@1.22.12: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + responselike@3.0.0: + dependencies: + lowercase-keys: 3.0.0 + + retry@0.13.1: {} + + reusify@1.1.0: {} + + rtlcss@4.3.0: + dependencies: + escalade: 3.2.0 + picocolors: 1.1.1 + postcss: 8.5.9 + strip-json-comments: 3.1.1 + + run-applescript@7.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + sax@1.6.0: {} + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + schema-dts@1.1.5: {} + + schema-utils@3.3.0: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 6.14.0 + ajv-keywords: 3.5.2(ajv@6.14.0) + + schema-utils@4.3.3: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.18.0 + ajv-formats: 2.1.1(ajv@8.18.0) + ajv-keywords: 5.1.0(ajv@8.18.0) + + search-insights@2.17.3: {} + + section-matter@1.0.0: + dependencies: + extend-shallow: 2.0.1 + kind-of: 6.0.3 + + select-hose@2.0.0: {} + + selfsigned@5.5.0: + dependencies: + '@peculiar/x509': 1.14.3 + pkijs: 3.4.0 + + semver-diff@4.0.0: + dependencies: + semver: 7.7.4 + + semver@6.3.1: {} + + semver@7.7.4: {} + + send@0.19.2: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.1 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + + serve-handler@6.1.7: + dependencies: + bytes: 3.0.0 + content-disposition: 0.5.2 + mime-types: 2.1.18 + minimatch: 3.1.5 + path-is-inside: 1.0.2 + path-to-regexp: 3.3.0 + range-parser: 1.2.0 + + serve-index@1.9.2: + dependencies: + accepts: 1.3.8 + batch: 0.6.1 + debug: 2.6.9 + escape-html: 1.0.3 + http-errors: 1.8.1 + mime-types: 2.1.35 + parseurl: 1.3.3 + transitivePeerDependencies: + - supports-color + + serve-static@1.16.3: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.2 + transitivePeerDependencies: + - supports-color + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + setprototypeof@1.2.0: {} + + shallow-clone@3.0.1: + dependencies: + kind-of: 6.0.3 + + shallowequal@1.1.0: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shell-quote@1.8.3: {} + + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + signal-exit@3.0.7: {} + + sirv@2.0.4: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + + sisteransi@1.0.5: {} + + sitemap@7.1.3: + dependencies: + '@types/node': 17.0.45 + '@types/sax': 1.2.7 + arg: 5.0.2 + sax: 1.6.0 + + skin-tone@2.0.0: + dependencies: + unicode-emoji-modifier-base: 1.0.0 + + slash@3.0.0: {} + + slash@4.0.0: {} + + snake-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.8.1 + + sockjs@0.3.24: + dependencies: + faye-websocket: 0.11.4 + uuid: 8.3.2 + websocket-driver: 0.7.4 + + sort-css-media-queries@2.2.0: {} + + source-map-js@1.2.1: {} + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + source-map@0.7.6: {} + + space-separated-tokens@2.0.2: {} + + spdy-transport@3.0.0: + dependencies: + debug: 4.4.3 + detect-node: 2.1.0 + hpack.js: 2.1.6 + obuf: 1.1.2 + readable-stream: 3.6.2 + wbuf: 1.7.3 + transitivePeerDependencies: + - supports-color + + spdy@4.0.2: + dependencies: + debug: 4.4.3 + handle-thing: 2.0.1 + http-deceiver: 1.2.7 + select-hose: 2.0.0 + spdy-transport: 3.0.0 + transitivePeerDependencies: + - supports-color + + sprintf-js@1.0.3: {} + + srcset@4.0.0: {} + + statuses@1.5.0: {} + + statuses@2.0.2: {} + + std-env@3.10.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.2.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + stringify-object@3.3.0: + dependencies: + get-own-enumerable-property-symbols: 3.0.2 + is-obj: 1.0.1 + is-regexp: 1.0.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + + strip-bom-string@1.0.0: {} + + strip-final-newline@2.0.0: {} + + strip-json-comments@2.0.1: {} + + strip-json-comments@3.1.1: {} + + style-to-js@1.1.21: + dependencies: + style-to-object: 1.0.14 + + style-to-object@1.0.14: + dependencies: + inline-style-parser: 0.2.7 + + stylehacks@6.1.1(postcss@8.5.9): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.9 + postcss-selector-parser: 6.1.2 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + svg-parser@2.0.4: {} + + svgo@3.3.3: + dependencies: + commander: 7.2.0 + css-select: 5.2.2 + css-tree: 2.3.1 + css-what: 6.2.2 + csso: 5.0.5 + picocolors: 1.1.1 + sax: 1.6.0 + + tapable@2.3.2: {} + + terser-webpack-plugin@5.4.0(webpack@5.106.1): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + terser: 5.46.1 + webpack: 5.106.1 + optional: true + + terser-webpack-plugin@5.4.0(webpack@5.95.0): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + terser: 5.46.1 + webpack: 5.95.0 + + terser@5.46.1: + dependencies: + '@jridgewell/source-map': 0.3.11 + acorn: 8.16.0 + commander: 2.20.3 + source-map-support: 0.5.21 + + thingies@2.6.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + + thunky@1.1.0: {} + + tiny-invariant@1.3.3: {} + + tiny-warning@1.0.3: {} + + tinypool@1.1.1: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + totalist@3.0.1: {} + + tree-dump@1.1.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + + trim-lines@3.0.1: {} + + trough@2.2.0: {} + + tslib@1.14.1: {} + + tslib@2.8.1: {} + + tsyringe@4.10.0: + dependencies: + tslib: 1.14.1 + + type-fest@0.21.3: {} + + type-fest@1.4.0: {} + + type-fest@2.19.0: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + typedarray-to-buffer@3.1.5: + dependencies: + is-typedarray: 1.0.0 + + typescript@5.9.3: {} + + undici-types@7.19.2: {} + + unicode-canonical-property-names-ecmascript@2.0.1: {} + + unicode-emoji-modifier-base@1.0.0: {} + + unicode-match-property-ecmascript@2.0.0: + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.1 + unicode-property-aliases-ecmascript: 2.2.0 + + unicode-match-property-value-ecmascript@2.2.1: {} + + unicode-property-aliases-ecmascript@2.2.0: {} + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unique-string@3.0.0: + dependencies: + crypto-random-string: 4.0.0 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position-from-estree@2.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + universalify@2.0.1: {} + + unpipe@1.0.0: {} + + update-browserslist-db@1.2.3(browserslist@4.28.2): + dependencies: + browserslist: 4.28.2 + escalade: 3.2.0 + picocolors: 1.1.1 + + update-notifier@6.0.2: + dependencies: + boxen: 7.1.1 + chalk: 5.6.2 + configstore: 6.0.0 + has-yarn: 3.0.0 + import-lazy: 4.0.0 + is-ci: 3.0.1 + is-installed-globally: 0.4.0 + is-npm: 6.1.0 + is-yarn-global: 0.4.1 + latest-version: 7.0.0 + pupa: 3.3.0 + semver: 7.7.4 + semver-diff: 4.0.0 + xdg-basedir: 5.1.0 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + url-loader@4.1.1(file-loader@6.2.0(webpack@5.106.1))(webpack@5.95.0): + dependencies: + loader-utils: 2.0.4 + mime-types: 2.1.35 + schema-utils: 3.3.0 + webpack: 5.95.0 + optionalDependencies: + file-loader: 6.2.0(webpack@5.106.1) + + util-deprecate@1.0.2: {} + + utila@0.4.0: {} + + utility-types@3.11.0: {} + + utils-merge@1.0.1: {} + + uuid@8.3.2: {} + + value-equal@1.0.1: {} + + vary@1.1.2: {} + + vfile-location@5.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile: 6.0.3 + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + watchpack@2.5.1: + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + + wbuf@1.7.3: + dependencies: + minimalistic-assert: 1.0.1 + + web-namespaces@2.0.1: {} + + webpack-bundle-analyzer@4.10.2: + dependencies: + '@discoveryjs/json-ext': 0.5.7 + acorn: 8.16.0 + acorn-walk: 8.3.5 + commander: 7.2.0 + debounce: 1.2.1 + escape-string-regexp: 4.0.0 + gzip-size: 6.0.0 + html-escaper: 2.0.2 + opener: 1.5.2 + picocolors: 1.1.1 + sirv: 2.0.4 + ws: 7.5.10 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.95.0): + dependencies: + colorette: 2.0.20 + memfs: 4.57.1(tslib@2.8.1) + mime-types: 3.0.2 + on-finished: 2.4.1 + range-parser: 1.2.1 + schema-utils: 4.3.3 + optionalDependencies: + webpack: 5.95.0 + transitivePeerDependencies: + - tslib + + webpack-dev-server@5.2.3(tslib@2.8.1)(webpack@5.95.0): + dependencies: + '@types/bonjour': 3.5.13 + '@types/connect-history-api-fallback': 1.5.4 + '@types/express': 4.17.25 + '@types/express-serve-static-core': 4.19.8 + '@types/serve-index': 1.9.4 + '@types/serve-static': 1.15.10 + '@types/sockjs': 0.3.36 + '@types/ws': 8.18.1 + ansi-html-community: 0.0.8 + bonjour-service: 1.3.0 + chokidar: 3.6.0 + colorette: 2.0.20 + compression: 1.8.1 + connect-history-api-fallback: 2.0.0 + express: 4.22.1 + graceful-fs: 4.2.11 + http-proxy-middleware: 2.0.9(@types/express@4.17.25) + ipaddr.js: 2.3.0 + launch-editor: 2.13.2 + open: 10.2.0 + p-retry: 6.2.1 + schema-utils: 4.3.3 + selfsigned: 5.5.0 + serve-index: 1.9.2 + sockjs: 0.3.24 + spdy: 4.0.2 + webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.95.0) + ws: 8.20.0 + optionalDependencies: + webpack: 5.95.0 + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - tslib + - utf-8-validate + + webpack-merge@5.10.0: + dependencies: + clone-deep: 4.0.1 + flat: 5.0.2 + wildcard: 2.0.1 + + webpack-merge@6.0.1: + dependencies: + clone-deep: 4.0.1 + flat: 5.0.2 + wildcard: 2.0.1 + + webpack-sources@3.3.4: {} + + webpack@5.106.1: + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.16.0 + acorn-import-phases: 1.0.4(acorn@8.16.0) + browserslist: 4.28.2 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.20.1 + es-module-lexer: 2.0.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.1 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 4.3.3 + tapable: 2.3.2 + terser-webpack-plugin: 5.4.0(webpack@5.106.1) + watchpack: 2.5.1 + webpack-sources: 3.3.4 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + optional: true + + webpack@5.95.0: + dependencies: + '@types/estree': 1.0.8 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.16.0 + acorn-import-attributes: 1.9.5(acorn@8.16.0) + browserslist: 4.28.2 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.20.1 + es-module-lexer: 1.7.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.1 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 3.3.0 + tapable: 2.3.2 + terser-webpack-plugin: 5.4.0(webpack@5.95.0) + watchpack: 2.5.1 + webpack-sources: 3.3.4 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + + webpackbar@6.0.1(webpack@5.95.0): + dependencies: + ansi-escapes: 4.3.2 + chalk: 4.1.2 + consola: 3.4.2 + figures: 3.2.0 + markdown-table: 2.0.0 + pretty-time: 1.1.0 + std-env: 3.10.0 + webpack: 5.95.0 + wrap-ansi: 7.0.0 + + websocket-driver@0.7.4: + dependencies: + http-parser-js: 0.5.10 + safe-buffer: 5.2.1 + websocket-extensions: 0.1.4 + + websocket-extensions@0.1.4: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + widest-line@4.0.1: + dependencies: + string-width: 5.1.2 + + wildcard@2.0.1: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.2.0 + + write-file-atomic@3.0.3: + dependencies: + imurmurhash: 0.1.4 + is-typedarray: 1.0.0 + signal-exit: 3.0.7 + typedarray-to-buffer: 3.1.5 + + ws@7.5.10: {} + + ws@8.20.0: {} + + wsl-utils@0.1.0: + dependencies: + is-wsl: 3.1.1 + + xdg-basedir@5.1.0: {} + + xml-js@1.6.11: + dependencies: + sax: 1.6.0 + + yallist@3.1.1: {} + + yocto-queue@1.2.2: {} + + zwitch@2.0.4: {} diff --git a/docs-site/sidebars.ts b/docs-site/sidebars.ts new file mode 100644 index 00000000..a55a2291 --- /dev/null +++ b/docs-site/sidebars.ts @@ -0,0 +1,23 @@ +import type { SidebarsConfig } from '@docusaurus/plugin-content-docs'; + +const sidebars: SidebarsConfig = { + docsSidebar: [ + { type: 'doc', id: 'about', label: 'About' }, + { type: 'doc', id: 'getting-started', label: 'Getting Started' }, + { type: 'doc', id: 'cli', label: 'CLI Reference' }, + { type: 'doc', id: 'api', label: 'API Reference' }, + { type: 'doc', id: 'auto-translation', label: 'Auto-Translation' }, + { + type: 'category', + label: 'Features', + items: [{ type: 'autogenerated', dirName: 'features' }], + }, + { + type: 'category', + label: 'Guides', + items: [{ type: 'autogenerated', dirName: 'guides' }], + }, + ], +}; + +export default sidebars; diff --git a/docs-site/src/css/custom.css b/docs-site/src/css/custom.css new file mode 100644 index 00000000..f9a6b4b0 --- /dev/null +++ b/docs-site/src/css/custom.css @@ -0,0 +1,168 @@ +/* Google Fonts — Watercolor design system */ +@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap'); + +/* ─── Light theme ─────────────────────────────────────────────────────────── */ +:root { + /* Primary — Warm Coral */ + --ifm-color-primary: #d4726a; + --ifm-color-primary-dark: #c25d55; + --ifm-color-primary-darker: #b95750; + --ifm-color-primary-darkest: #9d413a; + --ifm-color-primary-light: #da8880; + --ifm-color-primary-lighter: #de9189; + --ifm-color-primary-lightest: #e8a9a3; + + /* Fonts */ + --ifm-font-family-base: 'Nunito', sans-serif; + --ifm-font-family-monospace: 'IBM Plex Mono', monospace; + --ifm-code-font-size: 90%; + + /* Background & text */ + --ifm-background-color: #faf8f5; + --ifm-background-surface-color: #f5f1eb; + --ifm-font-color-base: #2e2923; + --ifm-font-color-secondary: #5a534a; + + /* Navbar */ + --ifm-navbar-background-color: #faf8f5; + --ifm-navbar-shadow: 0 1px 3px 0 rgb(44 36 28 / 0.08); + + /* Sidebar */ + --ifm-sidebar-background-color: #f5f1eb; + + /* Footer */ + --ifm-footer-background-color: #2e2923; + --ifm-footer-color: #d4cdc3; + --ifm-footer-link-color: #d4cdc3; + --ifm-footer-link-hover-color: #e8847c; + --ifm-footer-title-color: #f3efe9; + + /* Links */ + --ifm-link-color: #4a7fb5; + --ifm-link-hover-color: #3a6a9e; + + /* Code blocks */ + --ifm-code-background: #ede8e0; + --docusaurus-highlighted-code-line-bg: rgb(212 114 106 / 0.1); + + /* Borders */ + --ifm-color-emphasis-300: #e5dfd7; + --ifm-color-emphasis-400: #d4cdc3; + --ifm-hr-border-color: #e5dfd7; + --ifm-toc-border-color: #e5dfd7; + --ifm-table-border-color: #e5dfd7; + + /* Border radius */ + --ifm-global-radius: 0.5rem; + --ifm-code-border-radius: 0.375rem; + + /* Shadows */ + --ifm-global-shadow-md: 0 4px 8px -1px rgb(44 36 28 / 0.08), 0 2px 4px -2px rgb(44 36 28 / 0.06); + --ifm-global-shadow-lw: 0 1px 3px 0 rgb(44 36 28 / 0.06); + + /* Alerts */ + --ifm-color-success: #6da67e; + --ifm-color-warning: #d9a441; + --ifm-color-danger: #c95e5e; + --ifm-color-info: #4a7fb5; +} + +/* ─── Dark theme ──────────────────────────────────────────────────────────── */ +[data-theme='dark'] { + /* Primary — brightened Coral */ + --ifm-color-primary: #e8847c; + --ifm-color-primary-dark: #e06e65; + --ifm-color-primary-darker: #d4726a; + --ifm-color-primary-darkest: #c25d55; + --ifm-color-primary-light: #f0a09a; + --ifm-color-primary-lighter: #f4b0ab; + --ifm-color-primary-lightest: #f8c8c4; + + /* Background & text */ + --ifm-background-color: #141210; + --ifm-background-surface-color: #1c1814; + --ifm-font-color-base: #f3efe9; + --ifm-font-color-secondary: #d4cdc3; + + /* Navbar */ + --ifm-navbar-background-color: #1c1814; + --ifm-navbar-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.3); + + /* Sidebar */ + --ifm-sidebar-background-color: #1c1814; + + /* Footer */ + --ifm-footer-background-color: #0e0c0a; + --ifm-footer-color: #a89f93; + --ifm-footer-link-color: #a89f93; + --ifm-footer-link-hover-color: #e8847c; + --ifm-footer-title-color: #d4cdc3; + + /* Links */ + --ifm-link-color: #7bafde; + --ifm-link-hover-color: #9dc4e8; + + /* Code blocks */ + --ifm-code-background: #2e2923; + --docusaurus-highlighted-code-line-bg: rgb(232 132 124 / 0.12); + + /* Borders */ + --ifm-color-emphasis-300: #433d36; + --ifm-color-emphasis-400: #5a534a; + --ifm-hr-border-color: #433d36; + --ifm-toc-border-color: #433d36; + --ifm-table-border-color: #433d36; + + /* Shadows */ + --ifm-global-shadow-md: 0 4px 8px -1px rgb(0 0 0 / 0.35), 0 2px 4px -2px rgb(0 0 0 / 0.25); + --ifm-global-shadow-lw: 0 1px 3px 0 rgb(0 0 0 / 0.25); + + /* Alerts */ + --ifm-color-success: #7dbb8f; + --ifm-color-warning: #e4b454; + --ifm-color-danger: #d97878; + --ifm-color-info: #7bafde; +} + +/* ─── Body texture ────────────────────────────────────────────────────────── */ +body::after { + content: ''; + position: fixed; + inset: 0; + pointer-events: none; + z-index: 9999; + opacity: 1; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)' opacity='0.035'/%3E%3C/svg%3E"); +} + +/* ─── Navbar ──────────────────────────────────────────────────────────────── */ +.navbar__logo img { + height: 28px; +} + +.navbar__brand { + gap: 0.5rem; +} + +.navbar__title { + font-weight: 700; + font-size: 1.1rem; +} + +/* ─── Sidebar ─────────────────────────────────────────────────────────────── */ +.menu__link--active { + font-weight: 600; +} + +/* ─── Code ────────────────────────────────────────────────────────────────── */ +code { + border-radius: var(--ifm-code-border-radius); +} + +/* ─── Markdown ────────────────────────────────────────────────────────────── */ +article h1, +article h2, +article h3, +article h4 { + font-weight: 700; +} diff --git a/docs-site/src/pages/index.md b/docs-site/src/pages/index.md new file mode 100644 index 00000000..eed3ed2f --- /dev/null +++ b/docs-site/src/pages/index.md @@ -0,0 +1,7 @@ +--- +slug: / +--- + + + + diff --git a/docs-site/static/img/.gitkeep b/docs-site/static/img/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/docs-site/static/img/favicon.png b/docs-site/static/img/favicon.png new file mode 100644 index 00000000..c5cdceed Binary files /dev/null and b/docs-site/static/img/favicon.png differ diff --git a/docs-site/static/img/logo-dark.png b/docs-site/static/img/logo-dark.png new file mode 100644 index 00000000..77726cfe Binary files /dev/null and b/docs-site/static/img/logo-dark.png differ diff --git a/docs-site/static/img/logo.png b/docs-site/static/img/logo.png new file mode 100644 index 00000000..111a95db Binary files /dev/null and b/docs-site/static/img/logo.png differ diff --git a/docs-site/tsconfig.json b/docs-site/tsconfig.json new file mode 100644 index 00000000..2928c49b --- /dev/null +++ b/docs-site/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "target": "ES2017", + "lib": ["ES2017", "DOM"], + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "jsx": "react", + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "skipLibCheck": true, + "noEmit": true + } +} diff --git a/docs/about.md b/docs/about.md index 1fe50e62..146fe98f 100644 --- a/docs/about.md +++ b/docs/about.md @@ -1,3 +1,8 @@ +--- +title: About +sidebar_position: 1 +--- + # About LingoTracker LingoTracker is a comprehensive translation management tool designed as the ultimate companion to the [Transloco](https://github.com/jsverse/transloco) library. It provides developers and teams with an efficient, scalable solution for managing translation resources across multiple languages. @@ -16,16 +21,17 @@ LingoTracker streamlines the entire translation workflow by providing intelligen - **Type Safety**: Compile-time translation key validation with full IDE completion support - **Auto-Translation**: Machine translation via Google Translate with ICU-aware placeholder protection - **CI/CD Integration**: Powerful CLI for automated validation in build pipelines +- **REST API & Web UI**: Browser-based resource editor backed by a REST API, enabling team workflows and external integrations - **Format Flexibility**: Import/export support for JSON, XLIFF, and other translation formats - **Resource Linking**: Symlink support for sharing resources across projects - **Explicit Status Workflow**: `new`, `translated`, `stale`, `verified` with automatic updates on base changes - **Entry Tagging**: Tags stored alongside entries for rich filtering and export -- **Deterministic Checksums**: MD5-based checksums for both base and translated values -- **Strict Key Rules**: Dot-delimited keys; per-segment allowed chars `[A-Za-z0-9_-]+`; no de-duplication with target folder +- **Structured Key Naming**: Dot-delimited keys with strict character rules ensure predictable, conflict-free resource paths +- **AI Integration**: Installable Claude Code skill for AI-assisted translation workflows — detect hardcoded strings, create resources, and update components directly from your AI coding assistant ## Who It's For -LingoTracker is ideal for development teams working on internationalized applications who need reliable, scalable translation management. Whether you're managing a small project with a few languages or an enterprise application with hundreds of translation keys, LingoTracker adapts to your needs. +LingoTracker is ideal for development teams working on internationalized applications who need reliable, scalable translation management. Whether you're managing a small project with a few languages or an enterprise application with thousands of translation keys, LingoTracker adapts to your needs. ## Technology Integration diff --git a/docs/api.md b/docs/api.md index e1f20ed7..9d3ec9e9 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,3 +1,8 @@ +--- +title: API Reference +sidebar_position: 4 +--- + # LingoTracker API Reference ## Overview @@ -13,7 +18,7 @@ The LingoTracker API provides REST endpoints for managing translation resources, ## Authentication -Currently, the API does not require authentication. All endpoints are publicly accessible. +Currently, the API does not require authentication. It is meant to run on your machine when you need it. ## Health Check @@ -148,7 +153,7 @@ interface LingoTrackerCollectionDto { ``` **Status Codes**: -- `200 OK`: Collection created successfully +- `201 Created`: Collection created successfully - `400 Bad Request`: Invalid request body or collection already exists - `500 Internal Server Error`: Unexpected error during collection creation @@ -188,6 +193,54 @@ Response: } ``` +### Update Collection + +Updates or renames an existing collection. + +**Endpoint**: `PUT /api/collections/:collectionName` + +**Path Parameters**: +- `collectionName` (string, required): The name of the collection to update (URL-encoded if necessary) + +**Request Body**: + +```typescript +interface UpdateCollectionDto { + /** Optional new name to rename the collection */ + name?: string; + /** Updated collection configuration */ + collection: LingoTrackerCollectionDto; +} +``` + +**Response**: + +```json +{ + "message": "Collection 'admin-portal' updated successfully" +} +``` + +**Status Codes**: +- `200 OK`: Collection updated successfully +- `400 Bad Request`: Invalid request body or collection not found +- `500 Internal Server Error`: Unexpected error during update + +**Example**: + +```bash +curl -X PUT http://localhost:3030/api/collections/admin-portal \ + -H "Content-Type: application/json" \ + -d '{ + "name": "admin-portal-v2", + "collection": { + "translationsFolder": "./apps/admin/src/i18n", + "baseLocale": "en", + "locales": ["en", "es", "fr", "de"] + } + }' +``` + ### Delete Collection Deletes a collection by name. @@ -237,6 +290,88 @@ Response: } ``` +## Locales API + +Manage locales within a specific collection. + +### Add Locale + +Adds a locale to a collection and backfills all existing resources with the new locale (value set to the base value, `status: "new"`). + +**Endpoint**: `POST /api/collections/:collectionName/locales` + +**Path Parameters**: +- `collectionName` (string, required): The name of the collection (URL-encoded if necessary) + +**Request Body**: + +```json +{ + "locale": "de" +} +``` + +**Response**: + +```json +{ + "message": "Locale \"de\" added to collection \"main\" successfully", + "entriesBackfilled": 42, + "filesUpdated": 8 +} +``` + +**Status Codes**: +- `200 OK`: Locale added and resources backfilled +- `400 Bad Request`: Invalid locale format, locale already exists, cannot modify base locale, or collection not found + +**Example**: + +```bash +curl -X POST http://localhost:3030/api/collections/main/locales \ + -H 'Content-Type: application/json' \ + -d '{"locale": "de"}' +``` + +--- + +### Remove Locale + +Removes a locale from a collection and purges all translation data for that locale from resource files. + +**Endpoint**: `DELETE /api/collections/:collectionName/locales/:locale` + +**Path Parameters**: +- `collectionName` (string, required): The name of the collection (URL-encoded if necessary) +- `locale` (string, required): The locale to remove (URL-encoded if necessary) + +**Response**: + +```json +{ + "message": "Locale \"de\" removed from collection \"main\" successfully", + "entriesPurged": 42, + "filesUpdated": 8 +} +``` + +**Status Codes**: +- `200 OK`: Locale removed and data purged +- `400 Bad Request`: Invalid locale format, locale not found in collection, cannot modify base locale, or collection not found + +**Example**: + +```bash +curl -X DELETE http://localhost:3030/api/collections/main/locales/de +``` + +**Notes**: +- Translation data for the removed locale is permanently deleted from files (recoverable via git) +- Removing the last non-base locale is allowed +- Cannot remove the base locale + +--- + ## Resources API All resource endpoints are scoped to a specific collection. @@ -358,6 +493,11 @@ interface CreateResourceResponseDto { entriesCreated: number; /** Whether at least one resource entry was newly created */ created: boolean; + /** + * Locales skipped during auto-translation (ICU message format not supported). + * Only present when auto-translation is enabled and some locales were skipped. + */ + skippedLocales?: string[]; } ``` @@ -371,7 +511,7 @@ interface CreateResourceResponseDto { ``` **Status Codes**: -- `200 OK`: Resources processed successfully (check `entriesCreated` to see how many were new) +- `201 Created`: Resources processed successfully (check `entriesCreated` to see how many were new) - `400 Bad Request`: Invalid request body, validation error, or empty resource array - `404 Not Found`: Collection not found - `500 Internal Server Error`: Unexpected error during resource creation @@ -717,11 +857,10 @@ interface UpdateResourceDto { tags?: string[]; /** Optional target folder override */ targetFolder?: string; - /** Optional base locale override */ - baseLocale?: string; /** Optional map of locale updates */ locales?: Record; } ``` @@ -750,6 +889,13 @@ interface UpdateResourceResponseDto { updated: boolean; /** Optional message (e.g., "No changes detected") */ message?: string; + /** The updated resource data (present when updated is true) */ + resource?: ResourceSummaryDto; + /** + * Locales skipped during auto-translation (ICU message format not supported). + * Only present when auto-translation is enabled and some locales were skipped. + */ + skippedLocales?: string[]; } ``` @@ -773,7 +919,7 @@ interface UpdateResourceResponseDto { - Updating a locale value will set its status to `translated` and update its checksums. - If no changes are detected (values match existing), `updated` will be `false`. -## Move Resource(s) +### Move Resource(s) Moves or renames translation resources within a collection. Supports single resource moves and wildcard pattern moves. @@ -857,7 +1003,481 @@ interface MoveResourceResponseDto { - Wildcard moves (`source: "prefix.*"`) will move all matching resources to the `destination` prefix. - The operation is atomic per move entry but not transactional across all moves. +### Get Resource Tree + +Returns the resource tree for a collection, optionally scoped to a sub-path. The tree is built from an in-memory cache — the first request triggers background indexing and returns a `202 Accepted` with a status response until the cache is ready. + +**Endpoint**: `GET /api/collections/:collectionName/resources/tree` + +**Path Parameters**: +- `collectionName` (string, required): The name of the collection + +**Query Parameters**: +- `path` (string, optional): Dot-delimited folder path to scope the tree (e.g., `apps.common`) +- `includeNested` (boolean, optional): When `true` and `path` is set, returns all nested resources flattened into the `resources` array + +**Response** (cache ready — `200 OK`): + +```typescript +interface ResourceTreeDto { + /** Current folder path (dot-delimited, empty for root) */ + path: string; + /** Resources in this folder */ + resources: ResourceSummaryDto[]; + /** Child folders */ + children: FolderNodeDto[]; +} + +interface ResourceSummaryDto { + key: string; + translations: Record; + status: Record; + comment?: string; + tags?: string[]; +} + +interface FolderNodeDto { + name: string; + fullPath: string; + loaded: boolean; + tree?: ResourceTreeDto; +} +``` + +**Response** (cache not ready — `202 Accepted`): + +```typescript +interface TreeStatusResponseDto { + status: 'not-ready' | 'indexing'; + message: string; +} +``` + +**Status Codes**: +- `200 OK`: Tree returned successfully +- `202 Accepted`: Cache is indexing — retry shortly +- `404 Not Found`: Collection or path not found +- `500 Internal Server Error`: Unexpected error + +**Example**: + +```bash +# Full tree +curl http://localhost:3030/api/collections/web-app/resources/tree + +# Scoped subtree +curl "http://localhost:3030/api/collections/web-app/resources/tree?path=apps.common" + +# Scoped subtree with all nested resources +curl "http://localhost:3030/api/collections/web-app/resources/tree?path=apps.common&includeNested=true" +``` + +### Get Cache Status + +Returns the current indexing status of a collection's resource cache. + +**Endpoint**: `GET /api/collections/:collectionName/resources/cache/status` + +**Response**: + +```typescript +interface CacheStatusDto { + status: 'not-started' | 'indexing' | 'ready' | 'error'; + collectionName?: string; + /** ISO date string — present when status is 'ready' */ + indexedAt?: string; + /** Error message — present when status is 'error' */ + error?: string; + /** Collection statistics — present when status is 'ready' */ + stats?: { + totalKeys: number; + localeCount: number; + }; +} +``` + +**Example Response**: + +```json +{ + "status": "ready", + "collectionName": "web-app", + "indexedAt": "2026-04-09T12:00:00.000Z", + "stats": { + "totalKeys": 342, + "localeCount": 4 + } +} +``` + +**Status Codes**: +- `200 OK`: Status retrieved +- `404 Not Found`: Collection not found +- `500 Internal Server Error`: Unexpected error + +**Example**: + +```bash +curl http://localhost:3030/api/collections/web-app/resources/cache/status +``` + +### Search Translations + +Searches resources by key or translation value within a collection. Uses the in-memory cache when available, otherwise falls back to disk. + +**Endpoint**: `GET /api/collections/:collectionName/resources/search` + +**Query Parameters**: +- `query` (string, required): Search string (case-insensitive, matches keys and values) +- `maxResults` (number, optional): Maximum results to return. Default: `100`, max: `500` + +**Response**: + +```typescript +interface SearchResultsDto { + query: string; + results: SearchResultDto[]; + totalFound: number; + /** True when results were capped by maxResults */ + limited: boolean; +} + +interface SearchResultDto extends ResourceSummaryDto { + matchType: 'exact-key' | 'partial-key' | 'exact-value' | 'partial-value'; + /** Locales where value match was found */ + matchedLocales?: string[]; +} +``` + +**Example Response**: + +```json +{ + "query": "cancel", + "results": [ + { + "key": "apps.common.buttons.cancel", + "translations": { "en": "Cancel", "es": "Cancelar", "fr": "Annuler" }, + "status": { "en": null, "es": "verified", "fr": "translated" }, + "matchType": "partial-key" + } + ], + "totalFound": 1, + "limited": false +} +``` + +**Status Codes**: +- `200 OK`: Search completed +- `404 Not Found`: Collection not found +- `500 Internal Server Error`: Unexpected error + +**Example**: + +```bash +curl "http://localhost:3030/api/collections/web-app/resources/search?query=cancel&maxResults=50" +``` + +### Translate Resource + +Triggers auto-translation for a resource using the collection's configured translation provider. Returns an error if auto-translation is not enabled for the collection. + +**Endpoint**: `POST /api/collections/:collectionName/resources/translate` + +**Request Body**: + +```typescript +interface TranslateResourceDto { + /** Full dot-delimited key of the resource to translate */ + key: string; +} +``` + +**Response**: + +```typescript +interface TranslateResourceResponseDto { + /** The resource with translated values applied */ + resource: ResourceSummaryDto; + /** Number of locales successfully translated */ + translatedCount: number; + /** Locales skipped because the base value uses ICU message format */ + skippedLocales: string[]; +} +``` + +**Status Codes**: +- `201 Created`: Translation completed +- `404 Not Found`: Collection or resource not found +- `422 Unprocessable Entity`: Auto-translation not enabled for this collection +- `502 Bad Gateway`: Translation provider error +- `500 Internal Server Error`: Unexpected error + +**Example**: + +```bash +curl -X POST http://localhost:3030/api/collections/web-app/resources/translate \ + -H "Content-Type: application/json" \ + -d '{"key": "apps.common.buttons.cancel"}' +``` + +### Start Bulk Locale Translation Job + +Starts an async job that translates all `new` and `stale` resources in a collection for a single target locale. Returns immediately with a `jobId` that can be polled for progress. Requires auto-translation to be enabled for the collection. + +**Endpoint**: `POST /api/collections/:collectionName/resources/translate-locale` + +**Path Parameters**: +- `collectionName` (string, required): The name of the collection + +**Request Body**: + +```json +{ + "locale": "fr" +} +``` + +**Response** (202 Accepted): + +```typescript +interface TranslateLocaleJobDto { + jobId: string; + collectionName: string; + targetLocale: string; + status: 'pending' | 'running' | 'completed' | 'failed'; + totalResources: number; + translatedCount: number; + failedCount: number; + skippedCount: number; + failures?: Array<{ key: string; error: string }>; + skippedKeys?: string[]; + startedAt?: string; + completedAt?: string; +} +``` + +**Example Response**: + +```json +{ + "jobId": "uuid-here", + "collectionName": "playground", + "targetLocale": "fr", + "status": "pending", + "totalResources": 0, + "translatedCount": 0, + "failedCount": 0, + "skippedCount": 0 +} +``` + +**Status Codes**: +- `202 Accepted`: Job started — poll the GET endpoint for progress +- `400 Bad Request`: Invalid or missing locale +- `422 Unprocessable Entity`: Auto-translation not enabled for this collection +- `404 Not Found`: Collection not found +- `500 Internal Server Error`: Unexpected error + +**Example**: + +```bash +curl -X POST http://localhost:3030/api/collections/playground/resources/translate-locale \ + -H 'Content-Type: application/json' \ + -d '{"locale":"fr"}' +``` + +### Get Bulk Locale Translation Job Status + +Returns the current status and progress of a bulk locale translation job. Poll this endpoint every 2–5 seconds until `status` is `completed` or `failed`. + +**Endpoint**: `GET /api/collections/:collectionName/resources/translate-locale/:jobId` + +**Path Parameters**: +- `collectionName` (string, required): The name of the collection +- `jobId` (string, required): The job ID returned by the POST endpoint + +**Response**: + +`TranslateLocaleJobDto` with current status. See the POST endpoint above for the full type definition. + +**Status progression**: `pending` → `running` → `completed` / `failed` + +**Example Response** (completed): + +```json +{ + "jobId": "uuid-here", + "collectionName": "playground", + "targetLocale": "fr", + "status": "completed", + "totalResources": 48, + "translatedCount": 45, + "failedCount": 0, + "skippedCount": 3, + "failures": [], + "skippedKeys": ["forms.upload.acceptedFormats"], + "startedAt": "2026-04-11T12:00:00.000Z", + "completedAt": "2026-04-11T12:00:15.000Z" +} +``` + +**Status Codes**: +- `200 OK`: Job status returned +- `404 Not Found`: Collection or job not found +- `500 Internal Server Error`: Unexpected error + +**Example**: + +```bash +curl http://localhost:3030/api/collections/playground/resources/translate-locale/uuid-here +``` + +## Folders API + +All folder endpoints are scoped to a specific collection. + +### Create Folder + +Creates a new folder node in the resource hierarchy. + +**Endpoint**: `POST /api/collections/:collectionName/folders` + +**Request Body**: + +```typescript +interface CreateFolderDto { + /** Single-segment folder name (alphanumeric, dashes, underscores) */ + folderName: string; + /** Optional dot-delimited parent path (e.g., "apps.common"). Root if omitted. */ + parentPath?: string; +} +``` + +**Response**: + +```typescript +interface CreateFolderResponseDto { + /** Filesystem path of the created folder */ + folderPath: string; + /** False if the folder already existed */ + created: boolean; + /** The new folder node for inserting into the tree */ + folder: FolderNodeDto; +} +``` + +**Status Codes**: +- `201 Created`: Folder created (or already existed) +- `400 Bad Request`: Invalid folder name +- `404 Not Found`: Collection not found +- `500 Internal Server Error`: Unexpected error + +**Example**: + +```bash +curl -X POST http://localhost:3030/api/collections/web-app/folders \ + -H "Content-Type: application/json" \ + -d '{"folderName": "navigation", "parentPath": "apps.common"}' +``` + +### Delete Folder + +Deletes a folder and all resources within it. + +**Endpoint**: `DELETE /api/collections/:collectionName/folders` + +**Request Body**: + +```typescript +interface DeleteFolderDto { + /** Dot-delimited folder path to delete (e.g., "apps.common.buttons") */ + folderPath: string; +} +``` + +**Response**: + +```typescript +interface DeleteFolderResponseDto { + deleted: boolean; + folderPath: string; + /** Number of resource entries deleted with the folder */ + resourcesDeleted: number; + error?: string; +} +``` + +**Status Codes**: +- `200 OK`: Deletion attempted (check `deleted` and `error` fields) +- `400 Bad Request`: Invalid folder path +- `404 Not Found`: Collection not found +- `500 Internal Server Error`: Unexpected error + +**Example**: + +```bash +curl -X DELETE http://localhost:3030/api/collections/web-app/folders \ + -H "Content-Type: application/json" \ + -d '{"folderPath": "apps.common.buttons"}' +``` + +### Move Folder + +Moves a folder (and all its resources) to a new location. Supports cross-collection moves. + +**Endpoint**: `POST /api/collections/:collectionName/folders/move` + +**Request Body**: + +```typescript +interface MoveFolderDto { + /** Dot-delimited source folder path (e.g., "apps.common.buttons") */ + sourceFolderPath: string; + /** Dot-delimited destination folder path (e.g., "apps.shared") */ + destinationFolderPath: string; + /** If true, overwrite existing resources at destination. Default: false */ + override?: boolean; + /** Optional destination collection name for cross-collection moves */ + toCollection?: string; + /** + * When true, the source folder is nested under the destination as a child. + * Default: true + */ + nestUnderDestination?: boolean; +} +``` + +**Response**: + +```typescript +interface MoveFolderResponseDto { + movedCount: number; + foldersDeleted: number; + warnings: string[]; + errors: string[]; +} +``` + +**Status Codes**: +- `201 Created`: Move completed (check `movedCount` and `errors` for details) +- `400 Bad Request`: Invalid paths or validation error +- `404 Not Found`: Collection not found +- `500 Internal Server Error`: Unexpected error + +**Example**: + +```bash +curl -X POST http://localhost:3030/api/collections/web-app/folders/move \ + -H "Content-Type: application/json" \ + -d '{ + "sourceFolderPath": "apps.common.buttons", + "destinationFolderPath": "apps.shared", + "nestUnderDestination": true + }' +``` +## Error Handling All error responses follow a consistent format: diff --git a/docs/auto-translation.md b/docs/auto-translation.md index ded306ed..a3362dc6 100644 --- a/docs/auto-translation.md +++ b/docs/auto-translation.md @@ -1,10 +1,15 @@ +--- +title: Auto-Translation +sidebar_position: 5 +--- + # Auto-Translation LingoTracker can automatically translate new and stale resources using machine translation providers. This feature is opt-in and configured per-project or per-collection in `.lingo-tracker.json`. ## Overview -When auto-translation is enabled, adding or editing a resource can trigger machine translation for all target locales. The system classifies each string by its ICU content and applies the appropriate translation strategy: +When auto-translation is enabled, adding or editing a resource automatically triggers machine translation for all target locales — provided no explicit translations are supplied by the caller. The system classifies each string by its ICU content and applies the appropriate translation strategy: - **Plain text** is sent directly to the translation provider. - **Simple placeholders** (`{name}`, `{{ count }}`) are protected with markers before translation, then restored afterward. @@ -35,7 +40,9 @@ Add a `translation` block at the top level of your config file: "translation": { "enabled": true, "provider": "google-translate", - "apiKeyEnv": "GOOGLE_TRANSLATE_API_KEY" + "apiKeyEnv": "GOOGLE_TRANSLATE_API_KEY", + "batchSize": 5, + "delayMs": 1000 }, "collections": { "Main": { @@ -45,13 +52,15 @@ Add a `translation` block at the top level of your config file: } ``` -The `translation` block accepts three fields: +The `translation` block accepts the following fields: | Field | Type | Description | |---|---|---| | `enabled` | `boolean` | Whether auto-translation is active. Set to `false` to disable without removing the config. | | `provider` | `string` | The translation provider to use. Currently only `"google-translate"` is supported. | | `apiKeyEnv` | `string` | Name of the environment variable that holds the API key. The key is never stored in the config file. | +| `batchSize` | `number` | Number of resources to translate per API batch during bulk locale translation. Default: `5`. | +| `delayMs` | `number` | Milliseconds to wait between batches during bulk locale translation. Default: `1000`. | ### 2. Per-collection overrides @@ -71,9 +80,7 @@ A collection can override the global translation config. This is useful when dif "Admin": { "translationsFolder": "apps/admin/src/assets/i18n", "translation": { - "enabled": false, - "provider": "google-translate", - "apiKeyEnv": "GOOGLE_TRANSLATE_API_KEY" + "enabled": false } } } @@ -100,9 +107,9 @@ The translation orchestrator sits between callers and the translation provider. 1. **Classifies** the string using the ICU classifier (see below). 2. **Routes** the string based on classification: - - `plain` -- sends to the provider directly. - - `simple-placeholders` -- protects placeholders, sends, then restores. - - `complex-icu` -- returns the original value unchanged with `kind: 'skipped'`. + 1. `plain` -- sends to the provider directly. + 2. `simple-placeholders` -- protects placeholders, sends, then restores. + 3. `complex-icu` -- returns the original value unchanged with `kind: 'skipped'`. 3. **Returns** a result with `kind` indicating what happened: - `'translated'` -- plain text was translated. - `'translated-with-placeholders'` -- simple-placeholder text was translated with marker protection. @@ -178,6 +185,15 @@ The classifier normalizes Transloco's double-brace format (`{{ name }}`) to sing ## Usage +### CLI (add-resource and edit-resource) + +Auto-translation runs automatically during the `add-resource` and `edit-resource` CLI commands when `translation.enabled` is `true` in your config. No extra flags are needed. + +- **add-resource**: When no explicit translations are provided (interactively or via flags), the command delegates all target locales to the translation provider instead of populating them with the base value. +- **edit-resource**: When the base value is updated, the command triggers translation for any locale whose status is `new` or `stale`. + +Skipped locales (complex ICU strings) are left at their current status and surfaced in the CLI output for manual handling. + ### Translating existing resources via the API The API exposes an endpoint to translate an existing resource entry. Send a POST request with the resource key: @@ -215,6 +231,62 @@ If the base value uses complex ICU, `skippedLocales` will list the locales that Auto-translation targets locales where the translation status is `new` or `stale`, or where no metadata entry exists yet. Locales with status `translated` or `verified` are left unchanged. The base locale is always excluded. +## Bulk Locale Translation + +The `translate-locale` operation translates **all** `new` and `stale` resources in a collection for a single target locale in one command. This is useful for bootstrapping a new locale or catching up after a large batch of authoring changes. + +### CLI + +```bash +lingo-tracker translate-locale --collection --locale [--verbose] +``` + +In interactive mode (TTY), the command prompts for collection and locale when they are not provided. In non-interactive mode (CI/CD), both `--collection` and `--locale` are required. + +**Summary mode (default):** + +``` +Translating locale 'fr' in collection 'playground'... +Done. + +Translated: 45 resources +Skipped (ICU): 3 resources +Failed: 0 resources +``` + +**Verbose mode (`--verbose`):** + +``` +[batch 1/9] translated: 5, skipped: 0, failed: 0 +[batch 2/9] translated: 10, skipped: 0, failed: 0 +... +``` + +### API + +Bulk locale translation is exposed as an async job because large collections can take tens of seconds to translate. The workflow is: + +1. **Start the job** — `POST` to receive a `202 Accepted` response with a `jobId`. +2. **Poll for status** — `GET` with the `jobId` every 2–5 seconds until the status is `completed` or `failed`. + +See the [API reference](./api.md) for full endpoint documentation. + +### Throttling + +The `batchSize` and `delayMs` config fields control how aggressively the bulk operation calls the translation provider: + +- **`batchSize`** — how many resources are sent in each API call. Larger batches are faster but increase the risk of hitting per-request quotas. +- **`delayMs`** — how long to wait between batches. A non-zero delay smooths out rate-limit exposure over time. + +**Recommended settings:** + +| Tier | `batchSize` | `delayMs` | +|---|---|---| +| Free tier | `5` | `1000` | +| Paid tier | `50` | `0` | + +Start with the free-tier defaults and increase `batchSize` once you have confirmed your quota headroom. + ## Error Handling The translation system uses typed `TranslationError` instances with error codes: diff --git a/docs/cli.md b/docs/cli.md index d39e8ffc..0caefd45 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -1,3 +1,8 @@ +--- +title: CLI Reference +sidebar_position: 3 +--- + # CLI Reference This document provides a comprehensive reference for all Lingo Tracker CLI commands. For initial setup instructions, see the [Getting Started Guide](./getting-started.md). @@ -127,11 +132,11 @@ lingo-tracker add-collection [options] **Options:** -- `--collectionName ` - Name of the new collection (required in non-interactive mode) -- `--translationsFolder ` - Path to the translations directory for this collection (required in non-interactive mode) -- `--exportFolder ` - Override global export folder for this collection -- `--importFolder ` - Override global import folder for this collection -- `--baseLocale ` - Override global base locale +- `--collection-name ` - Name of the new collection (required in non-interactive mode) +- `--translations-folder ` - Path to the translations directory for this collection (required in non-interactive mode) +- `--export-folder ` - Override global export folder for this collection +- `--import-folder ` - Override global import folder for this collection +- `--base-locale ` - Override global base locale - `--locales ` - Override global locales list **Examples:** @@ -144,16 +149,16 @@ lingo-tracker add-collection Simple, using global defaults: ```bash lingo-tracker add-collection \ - --collectionName Admin \ - --translationsFolder apps/admin/src/assets/i18n + --collection-name Admin \ + --translations-folder apps/admin/src/assets/i18n ``` With collection-specific overrides (only differences are saved): ```bash lingo-tracker add-collection \ - --collectionName Mobile \ - --translationsFolder apps/mobile/src/i18n \ - --baseLocale en-GB + --collection-name Mobile \ + --translations-folder apps/mobile/src/i18n \ + --base-locale en-GB ``` **Notes:** @@ -176,7 +181,7 @@ lingo-tracker delete-collection [options] **Options:** -- `--collectionName ` - Name of the collection to delete (required in non-interactive mode) +- `--collection-name ` - Name of the collection to delete (required in non-interactive mode) **Examples:** @@ -187,7 +192,7 @@ lingo-tracker delete-collection Non-interactive mode: ```bash -lingo-tracker delete-collection --collectionName Mobile +lingo-tracker delete-collection --collection-name Mobile ``` **Notes:** @@ -197,6 +202,79 @@ lingo-tracker delete-collection --collectionName Mobile --- +### add-locale + +Add a locale to a collection and backfill all existing resources with the new locale. + +**Usage:** + +```bash +lingo-tracker add-locale [options] +``` + +**Options:** + +- `--collection ` - Name of the collection (required in non-interactive mode) +- `--locale ` - Locale to add, e.g. `fr-ca`, `de`, `es` (required in non-interactive mode) + +**Examples:** + +Interactive mode (prompts for collection and locale): +```bash +lingo-tracker add-locale +``` + +Non-interactive mode: +```bash +lingo-tracker add-locale --collection Main --locale de +``` + +**Notes:** +- Validates locale format (e.g. `en`, `fr-ca`, `zh-Hans`) +- Errors if the locale already exists in the collection +- Cannot add the base locale +- If the collection inherits global locales (no explicit `locales` in its config), global locales are copied into the collection first, then the new locale is appended +- All existing `resource_entries.json` files are updated with the new locale value set to the base (`source`) value, and `tracker_meta.json` is updated with `status: "new"` + +--- + +### remove-locale + +Remove a locale from a collection and purge all of its translation data from resource files. + +**Usage:** + +```bash +lingo-tracker remove-locale [options] +``` + +**Options:** + +- `--collection ` - Name of the collection (required in non-interactive mode) +- `--locale ` - Locale to remove (required in non-interactive mode) + +**Examples:** + +Interactive mode (prompts for collection, then shows a list of removable locales): +```bash +lingo-tracker remove-locale +``` + +Non-interactive mode: +```bash +lingo-tracker remove-locale --collection Main --locale de +``` + +**Notes:** +- Errors if the locale does not exist in the collection +- Cannot remove the base locale +- Removes the locale key from all `resource_entries.json` and `tracker_meta.json` files in the collection +- Translation data for the locale is permanently deleted from files (recoverable via git) +- Removing the last non-base locale is allowed (results in a monolingual collection) +- If the collection inherits global locales, global locales are copied into the collection first, then the target locale is removed + +--- + ## Resource Commands ### add-resource @@ -216,7 +294,7 @@ lingo-tracker add-resource [options] - `--value ` - Base (source) text in the base locale (required in non-interactive mode) - `--comment ` - Optional context for translators - `--tags ` - Optional comma-separated tags for filtering/exporting -- `--targetFolder ` - Optional dot-delimited path override for folder placement +- `--target-folder ` - Optional dot-delimited path override for folder placement - `--translations ` - Optional JSON array with translation objects **Translation Object Format:** @@ -263,13 +341,13 @@ lingo-tracker add-resource \ --value OK \ --comment "OK button in dialogs" \ --tags "ui,buttons,dialogs" \ - --targetFolder apps.common \ + --target-folder apps.common \ --translations '[{"locale":"es","value":"Aceptar","status":"translated"},{"locale":"fr-ca","value":"OK","status":"new"}]' ``` **Notes:** - In interactive mode, you'll be prompted if you want to provide translations for each configured locale -- Resources are placed in the appropriate folder based on the key and optional `--targetFolder` +- Resources are placed in the appropriate folder based on the key and optional `--target-folder` - If a translation's checksum matches the base value's checksum, the status will automatically be set to `new` regardless of the provided status --- @@ -362,12 +440,12 @@ lingo-tracker edit-resource [options] - `--collection ` - Collection containing the resource (required in non-interactive mode) - `--key ` - Resource key (required in non-interactive mode) -- `--baseValue ` - New base value (updates source text) +- `--base-value ` - New base value (updates source text) - `--comment ` - New comment - `--tags ` - New tags (comma-separated, replaces existing) -- `--targetFolder ` - New target folder -- `--locale ` - Locale to update (requires `--localeValue`) -- `--localeValue ` - New translation value for the specified locale +- `--target-folder ` - New target folder +- `--locale ` - Locale to update (requires `--locale-value`) +- `--locale-value ` - New translation value for the specified locale **Examples:** @@ -381,7 +459,7 @@ Update base value (marks other locales as stale): lingo-tracker edit-resource \ --collection Main \ --key buttons.save \ - --baseValue "Save Item" + --base-value "Save Item" ``` Update a specific translation: @@ -390,7 +468,7 @@ lingo-tracker edit-resource \ --collection Main \ --key buttons.save \ --locale fr-ca \ - --localeValue "Enregistrer l'article" + --locale-value "Enregistrer l'article" ``` Update metadata: @@ -403,12 +481,85 @@ lingo-tracker edit-resource \ ``` **Notes:** -- Updating `baseValue` triggers a checksum update and marks all other existing translations as `stale`. +- Updating `--base-value` triggers a checksum update and marks all other existing translations as `stale`. - Updating a locale value sets its status to `translated` and updates its checksum. - If no changes are detected (values match existing), the command reports "No changes detected". --- +### translate-locale + +Auto-translate all `new` and `stale` resources in a collection for a single target locale. Requires auto-translation to be enabled in `.lingo-tracker.json`. + +**Usage:** + +```bash +lingo-tracker translate-locale [options] +``` + +**Options:** + +- `--collection ` - Collection name (prompted if not provided) +- `--locale ` - Target locale to translate (prompted if not provided) +- `--verbose` - Show per-batch progress (default: summary only) + +**Interactive mode:** + +When running in a TTY environment without `--collection` or `--locale`, the command prompts for the missing values. + +**Non-interactive mode:** + +Both `--collection` and `--locale` are required. The command exits with a non-zero code if either is missing. + +**Examples:** + +Interactive mode (prompts for collection and locale): +```bash +lingo-tracker translate-locale +``` + +Non-interactive mode: +```bash +lingo-tracker translate-locale \ + --collection Main \ + --locale fr +``` + +With verbose progress: +```bash +lingo-tracker translate-locale \ + --collection Main \ + --locale fr \ + --verbose +``` + +**Output (summary mode):** + +``` +Translating locale 'fr' in collection 'playground'... +Done. + +Translated: 45 resources +Skipped (ICU): 3 resources +Failed: 0 resources +``` + +**Output (verbose mode):** + +``` +[batch 1/9] translated: 5, skipped: 0, failed: 0 +[batch 2/9] translated: 10, skipped: 0, failed: 0 +... +``` + +**Notes:** +- Only resources with status `new` or `stale` are translated; `translated` and `verified` resources are left unchanged +- Resources whose base value uses complex ICU syntax are skipped and reported in the "Skipped (ICU)" count +- Throttling is controlled by `batchSize` and `delayMs` in the `translation` config block; see [Auto-Translation](./auto-translation.md) for recommended settings +- Requires `translation.enabled: true` in `.lingo-tracker.json` + +--- + ### move Move or rename translation resources. Supports moving single resources as well as bulk moves using wildcard patterns. @@ -424,7 +575,6 @@ lingo-tracker move [options] - `--collection ` - Collection to move resources in (required in non-interactive mode) - `--source ` - Source key or pattern (e.g., `common.buttons.ok` or `common.buttons.*`) (required in non-interactive mode) - `--dest ` - Destination key (e.g., `common.actions.ok` or `common.actions`) (required in non-interactive mode) -- `--destCollection ` - Optional destination collection (defaults to source collection) - `--override` - Overwrite destination if it already exists - `--verbose` - Print detailed output for each moved resource @@ -452,15 +602,6 @@ lingo-tracker move \ ``` *Result: `common.buttons.ok` -> `common.actions.ok`, `common.buttons.cancel` -> `common.actions.cancel`* -Move resource to another collection: -```bash -lingo-tracker move \ - --collection Main \ - --source common.buttons.ok \ - --dest common.buttons.ok \ - --destCollection Admin -``` - Force move (overwrite destination): ```bash lingo-tracker move \ @@ -619,6 +760,7 @@ lingo-tracker bundle [options] - `--locale ` - Specific locale(s) to generate (comma-separated). If not specified, generates all locales - `--token-casing ` - Casing style for generated type token keys: `upperCase` or `camelCase`. Overrides any `tokenCasing` set in the config file. Default: `upperCase` - `--token-constant-name ` - Custom name for the generated TypeScript constant. Must be a valid JavaScript identifier. Only works when targeting a single bundle (via `--name`). Overrides `tokenConstantName` in the bundle config +- `--no-transform-icu-to-transloco` - Disable ICU to Transloco format conversion in bundle output - `--verbose` - Show detailed output including all warnings **What Bundle Generation Does:** @@ -1056,6 +1198,8 @@ The validate command performs a comprehensive check: --- +## Data Exchange Commands + ### export Export translation resources to XLIFF or JSON format for integration with translation services, external systems, and third-party tools. @@ -1304,7 +1448,138 @@ Every export generates an `export-summary.md` file in the output directory conta - Multiple collections merge into single output file per locale (last write wins) - Base locale is excluded from export (use bundle command for base locale) - Dry-run shows accurate resource counts without creating files -- For detailed format specifications and examples, see [Export Feature Documentation](../features/export.md) +- For detailed format specifications and examples, see [Export Feature Documentation](./features/export.md) + +--- + +### import + +Import translation resources from XLIFF or JSON files into a collection. Supports professional translation workflows, language expert verification, system migrations, and bulk corrections. + +For full format specifications, workflow examples, and ICU auto-fix details, see the [Import Feature Documentation](./features/import.md). + +**Usage:** + +```bash +lingo-tracker import --source --locale [options] +``` + +**Options:** + +- `-f, --format ` - Import format: `xliff` or `json`. Default: auto-detected from file extension (`.xlf`/`.xliff` → xliff; `.json` → json) +- `-s, --source ` - Path to the import file (required) +- `-l, --locale ` - Target locale for the import, e.g., `es`, `fr-ca` (required) +- `-c, --collection ` - Target collection to import into. If not specified, prompts or auto-selects +- `--strategy ` - Import strategy (see below). Default: `translation-service` +- `--update-comments` - Update resource comments from import data. Default: `false` +- `--update-tags` - Update resource tags from rich JSON. Default: `false` +- `--preserve-status` - Allow rich JSON to specify status (advanced). Default: `false` +- `--create-missing` - Create new resources if they don't exist +- `--validate-base` - Warn if the source base value differs from existing. Default: `true` +- `--dry-run` - Preview what would be imported without modifying files. Default: `false` +- `--verbose` - Show detailed import progress. Default: `false` + +**Import Strategies:** + +| Strategy | Description | +|----------|-------------| +| `translation-service` (default) | Sets status to `translated`. For translation agencies. Does not create missing resources. | +| `verification` | Sets status to `verified`. For native-speaker review and approval. Does not create missing resources. | +| `migration` | Sets status to `translated`. Creates missing resources (`--create-missing` defaults to `true`). Resolves Transloco-style key refs. Updates comments and tags by default. | +| `update` | Preserves existing status. Bulk-updates values without changing metadata. Does not create missing resources. | + +**Examples:** + +Interactive mode (prompts for all required values): +```bash +lingo-tracker import +``` + +Import XLIFF from a translation service (default strategy): +```bash +lingo-tracker import \ + --source dist/lingo-import/es.xliff \ + --locale es +``` + +Import with explicit strategy: +```bash +lingo-tracker import \ + --source dist/lingo-import/fr.xliff \ + --locale fr \ + --strategy translation-service +``` + +Import for language expert verification: +```bash +lingo-tracker import \ + --source fr-reviewed.xliff \ + --locale fr \ + --strategy verification +``` + +Migrate from another translation system (creates missing resources): +```bash +lingo-tracker import \ + --source old-system-fr.json \ + --locale fr \ + --strategy migration +``` + +Bulk-correct existing translations without changing status: +```bash +lingo-tracker import \ + --source corrections-de.json \ + --locale de \ + --strategy update +``` + +Dry-run to preview what would be imported: +```bash +lingo-tracker import \ + --source translations-es.xliff \ + --locale es \ + --dry-run +``` + +Verbose output to see detailed progress: +```bash +lingo-tracker import \ + --source translations-es.xliff \ + --locale es \ + --verbose +``` + +Import into a specific collection: +```bash +lingo-tracker import \ + --source admin-es.xliff \ + --locale es \ + --collection Admin \ + --strategy translation-service +``` + +**Round-Trip Workflow:** + +```bash +# 1. Export resources needing translation +lingo-tracker export --format xliff --locale es --status new,stale + +# 2. (Send es.xliff to translation agency, receive back translated file) + +# 3. Import translated file +lingo-tracker import --source es.xliff --locale es --strategy translation-service + +# 4. Optionally verify with a language expert +lingo-tracker import --source es-reviewed.xliff --locale es --strategy verification +``` + +**Notes:** +- Format is auto-detected from the file extension; use `--format` to override +- Every import generates an `import-summary.md` in the import folder with statistics, status transitions, ICU auto-fixes, warnings, and errors +- ICU message placeholder errors (renamed or missing placeholders) are automatically detected and fixed where possible; all auto-fixes are reported in the summary +- Dry-run mode produces the same summary report using "Would" language, with no files modified +- In interactive mode, a wizard guides you through source file selection, locale, collection, and strategy --- @@ -1431,15 +1706,15 @@ All commands support non-interactive mode for use in CI/CD pipelines. To ensure ```bash # Initialize a project in CI lingo-tracker init \ - --collectionName Main \ - --translationsFolder src/assets/i18n \ - --baseLocale en \ + --collection-name Main \ + --translations-folder src/assets/i18n \ + --base-locale en \ --locales en fr-ca es # Add a collection in CI lingo-tracker add-collection \ - --collectionName Admin \ - --translationsFolder src/admin/i18n + --collection-name Admin \ + --translations-folder src/admin/i18n # Add a resource in CI lingo-tracker add-resource \ diff --git a/docs/features/bundle-type-generation.md b/docs/features/bundle-type-generation.md index 2573714e..53ef8e03 100644 --- a/docs/features/bundle-type-generation.md +++ b/docs/features/bundle-type-generation.md @@ -1,3 +1,8 @@ +--- +title: Bundle Type Generation +sidebar_position: 1 +--- + # Bundle Type Generation LingoTracker can automatically generate TypeScript type definitions for your translation bundles. This provides compile-time type safety, autocomplete, and refactoring support for your translation keys. @@ -11,7 +16,7 @@ LingoTracker can automatically generate TypeScript type definitions for your tra ## Configuration -To enable type generation, add the `typeDistFile` property to your bundle definition in `.lingo-tracker.json`. This property specifies the output file path for the generated TypeScript file. The path must end with `.ts` and must point to a file, not a directory. +To enable type generation, add the `typeDistFile` property to your bundle definition in `.lingo-tracker.json`. This property specifies the output file path for the generated TypeScript file. The path must end with `.ts` and must point to a file, not a directory. Intermediate directories are created automatically if they do not exist. ```json { @@ -89,19 +94,19 @@ export const COMMON_TOKENS = { export type CommonTokens = typeof COMMON_TOKENS; ``` -**More Examples**: - -| Translation Key | `upperCase` (default) | `camelCase` | -|---|---|---| -| `file-upload` | `FILE_UPLOAD` | `fileUpload` | -| `common.buttons.ok` | `COMMON.BUTTONS.OK` | `common.buttons.ok` | - To use camelCase, set `tokenCasing` in your bundle config or pass `--token-casing camelCase` to the `bundle` CLI command: ```bash lingo-tracker bundle --token-casing camelCase ``` +**Property path comparison** (arrows indicate nested object levels): + +| Translation Key | `upperCase` (default) | `camelCase` | +|---|---|---| +| `file-upload` | `FILE_UPLOAD` | `fileUpload` | +| `common.buttons.ok` | `COMMON` → `BUTTONS` → `OK` | `common` → `buttons` → `ok` | + ## Token Casing Precedence The `tokenCasing` value is resolved in the following order (first match wins): @@ -115,7 +120,7 @@ The `tokenCasing` value is resolved in the following order (first match wins): By default, the generated constant name is derived from the bundle key (e.g., `common` → `COMMON_TOKENS`). You can override this with the `tokenConstantName` property in your bundle definition. -The value must be a valid JavaScript identifier. Any casing is accepted — the type name is always auto-derived as PascalCase from whatever you provide. +The value must be a valid JavaScript identifier using only ASCII characters (letters A–Z/a–z, digits, underscores `_`, and dollar signs `$`). Any casing is accepted — the type name is always auto-derived as PascalCase from whatever you provide. ```json { @@ -152,7 +157,7 @@ export type MyKeys = typeof MY_KEYS; | `MyKeys` | `MyKeys` | `MyKeys` | | `APP_TRANSLATION_TOKENS` | `APP_TRANSLATION_TOKENS` | `AppTranslationTokens` | -You can also override at the CLI level with `--token-constant-name`. This flag only works when targeting a single bundle: +You can also override at the CLI level with `--token-constant-name`. This flag requires exactly one bundle to be targeted via `--name`; it is not compatible with multi-bundle runs or "all bundles" mode: ```bash lingo-tracker bundle --name common --token-constant-name MY_KEYS @@ -165,28 +170,8 @@ lingo-tracker bundle --name common --token-constant-name MY_KEYS - **Key Segments (upperCase)**: Converted to `SCREAMING_SNAKE_CASE` (e.g., `buttons` -> `BUTTONS`, `file-upload` -> `FILE_UPLOAD`). - **Key Segments (camelCase)**: Converted to `camelCase` (e.g., `buttons` -> `buttons`, `file-upload` -> `fileUpload`). - **Numeric Segments**: Preserved as-is (e.g., `steps.1.title` -> `STEPS.1.TITLE` or `steps.1.title`). - -## Migration from `typeDist` - -> **Deprecation Notice**: The `typeDist` configuration property has been renamed to `typeDistFile` to clarify that the value must be a file path (ending with `.ts`), not a directory. - -- The old `typeDist` name is still accepted but will produce a deprecation warning at runtime. -- Users should update their `.lingo-tracker.json` to use `typeDistFile` instead of `typeDist`. -- The `typeDistFile` value must end with `.ts` and must be a file path, not a directory path. - -**Before**: -```json -{ - "typeDist": "./src/generated/common-tokens.ts" -} -``` - -**After**: -```json -{ - "typeDistFile": "./src/generated/common-tokens.ts" -} -``` +- **Mixed nodes** (a key that is both a leaf and a parent, e.g., `buttons` and `buttons.ok` both exist): the leaf value is dropped and only the children are emitted. Standard i18n usage does not produce such keys. +- **Empty bundles**: if the bundle resolves to zero keys, type generation is skipped and a warning is printed. No `.ts` file is written. ## Integration diff --git a/docs/features/export.md b/docs/features/export.md index 40f00e1b..7bd5c5cd 100644 --- a/docs/features/export.md +++ b/docs/features/export.md @@ -1,3 +1,8 @@ +--- +title: Export +sidebar_position: 2 +--- + # Export Feature The Export feature allows you to export translation resources from LingoTracker into standard formats (XLIFF and JSON) for integration with translation services and external systems. @@ -19,11 +24,11 @@ lingo-tracker export --format [options] |--------|-------------|---------| | `-f, --format ` | Export format (`xliff` or `json`). | Required (or interactive) | | `-c, --collection ` | Comma-separated list of collections to export. | All collections | -| `-l, --locale ` | Comma-separated list of target locales. | All target locales | +| `-l, --locale ` | Comma-separated list of target locales. The base locale is always excluded. | All target locales | | `-s, --status ` | Filter by status (`new`, `translated`, `stale`, `verified`). | `new,stale` | | `-t, --tags ` | Filter by tags (comma-separated). | None | -| `-o, --output ` | Output directory. | `dist/lingo-export` | -| `--filename ` | Custom filename pattern. | `{target}.xliff` or `{locale}.json` | +| `-o, --output ` | Output directory. Defaults to `exportFolder` from config if set. | `dist/lingo-export` | +| `--filename ` | Custom filename pattern. The extension (`.xliff` or `.json`) is appended automatically if omitted. | `.xliff` or `.json` | | `--dry-run` | Preview export without writing files. | `false` | | `--verbose` | Show detailed progress. | `false` | @@ -32,18 +37,17 @@ lingo-tracker export --format [options] | Option | Description | Default | |--------|-------------|---------| | `--structure ` | `hierarchical` or `flat`. | `hierarchical` | -| `--rich` | Output rich objects with metadata. | `false` | -| `--include-base` | Include base locale value. | `false` | -| `--include-status` | Include status in rich objects. | `false` | -| `--include-comment` | Include comments in rich objects. | `true` | -| `--include-tags` | Include tags in rich objects. | `false` | +| `--rich` | Output rich objects with metadata instead of plain string values. | `false` | +| `--include-base` | Include base locale value. Only applies when `--rich` is set. | `false` | +| `--include-status` | Include translation status. Only applies when `--rich` is set. | `false` | +| `--include-comment` | Include comments. Only applies when `--rich` is set. | `true` | +| `--include-tags` | Include tags array. Only applies when `--rich` is set. | `false` | ### Filename Placeholders -You can use the following placeholders in `--filename`: +You can use the following placeholders in `--filename`. If no file extension is included, the correct extension for the format (`.xliff` or `.json`) is appended automatically. -- `{locale}`: The target locale code (e.g., `es`, `fr-ca`). -- `{target}`: Alias for `{locale}`. +- `{locale}` / `{target}`: The target locale code (e.g., `es`, `fr-ca`). These are interchangeable. - `{source}`: The base locale code (e.g., `en`). - `{date}`: Current date (YYYY-MM-DD). @@ -53,13 +57,46 @@ lingo-tracker export --format json --filename "translations-{source}-to-{target} # Generates: translations-en-to-es-2025-12-13.json ``` +## Examples + +Export all untranslated and stale strings to XLIFF for all target locales: +```bash +lingo-tracker export --format xliff +``` + +Export only Spanish strings with `new` or `stale` status from a specific collection: +```bash +lingo-tracker export --format xliff --locale es --collection marketing --status new,stale +``` + +Export all target locales to flat JSON with a custom filename: +```bash +lingo-tracker export --format json --structure flat --filename "{locale}-translations" +# Generates: es-translations.json, fr-translations.json, etc. +``` + +Export rich JSON including base values and comments (useful for translator context): +```bash +lingo-tracker export --format json --rich --include-base --include-comment +``` + +Preview an export without writing any files: +```bash +lingo-tracker export --format xliff --dry-run +``` + ## Export Summary -Every export generates an `export-summary.md` file in the output directory containing: -- Export statistics (resources count, files created). -- List of warnings (e.g., overwritten files). -- List of errors (e.g., malformed files, missing metadata). +Every export generates an `export-summary.md` file in the output directory. It contains: + +- **Metadata**: date, format, collections, target locales, status and tag filters applied. +- **Results**: resources exported, files created, output directory. +- **File list**: each file generated (or that would be generated in a dry run). +- **Warnings**: e.g., files that were overwritten. +- **Errors**: broken down into general errors, malformed files, resources omitted due to missing metadata, and hierarchical key conflicts (JSON only — when a key like `a.b.c` conflicts with a parent key `a.b`). + +In a dry run, the summary is printed to the console instead of written to disk. Note: even in dry-run mode, the output directory is created on disk if it does not already exist. ## Interactive Mode -If you run `lingo-tracker export` without the `--format` flag in a terminal, it will launch an interactive wizard to guide you through the options. +If you run `lingo-tracker export` without the `--format` flag **in a TTY terminal**, an interactive wizard guides you through all options. In non-interactive environments (CI, pipes), `--format` is required and omitting it is an error. All other unspecified options fall back silently to their documented defaults — pass all relevant flags explicitly in scripts rather than relying on interactive prompts. diff --git a/docs/features/import.md b/docs/features/import.md index 10b11e93..3d897cf0 100644 --- a/docs/features/import.md +++ b/docs/features/import.md @@ -1,3 +1,8 @@ +--- +title: Import +sidebar_position: 3 +--- + # Import Feature The Import feature allows you to import translation resources from external sources in standard formats (XLIFF and JSON), supporting professional translation workflows, system migrations, and expert verification processes. @@ -5,6 +10,8 @@ The Import feature allows you to import translation resources from external sour ## Usage ```bash +lingo-tracker import -s -l [options] +# or lingo-tracker import --source --locale [options] ``` @@ -21,19 +28,21 @@ You can explicitly specify the format with `--format ` if needed. | Option | Description | Default | |--------|-------------|---------| -| `--source ` | Path to import file (required). | - | -| `--locale ` | Target locale for import (e.g., `es`, `fr-ca`). | - | -| `--format ` | Import format (`xliff` or `json`). | Auto-detect from extension | -| `--collection ` | Target collection to import into. | Default collection | +| `-s, --source ` | Path to import file (required). | - | +| `-l, --locale ` | Target locale for import (e.g., `es`, `fr-ca`). | - | +| `-f, --format ` | Import format (`xliff` or `json`). | Auto-detect from extension | +| `-c, --collection ` | Target collection to import into. | Default collection | | `--strategy ` | Import strategy (see below). | `translation-service` | -| `--update-comments` | Update resource comments from import data. | Strategy-dependent | -| `--update-tags` | Update resource tags from rich JSON. | Strategy-dependent | +| `--update-comments` | Update resource comments from import data. | `false` | +| `--update-tags` | Update resource tags from rich JSON. | `false` | | `--preserve-status` | Allow rich JSON to specify status (advanced). | `false` | | `--create-missing` | Create new resources if they don't exist. | Strategy-dependent | | `--validate-base` | Warn if source base value differs from existing. | `true` | | `--dry-run` | Preview import without modifying files. | `false` | | `--verbose` | Show detailed import progress. | `false` | +> **Note:** Files larger than 5 MB will show a warning before import begins. + ## Import Strategies Different import workflows require different approaches. The `--strategy` option selects the appropriate behavior: @@ -45,7 +54,7 @@ Different import workflows require different approaches. The `--strategy` option **Behavior**: - Sets status to `translated` for all imported values - Preserves existing base values (warns if source differs) -- Does NOT create new resources (skips with error if resource doesn't exist) +- Does NOT create new resources (skips missing resources; counted in Resources Skipped, not an error) - Does NOT update comments or tags by default **Typical Workflow**: @@ -80,19 +89,20 @@ lingo-tracker import --source verified-fr.xliff --locale fr --strategy verificat **Behavior**: - Creates new resources with base values from XLIFF `` or JSON `baseValue` -- Sets status to `translated` for all imports -- Expands Transloco key references (e.g., `{{t('other.key')}}`) into full values -- Updates comments and tags from import data by default +- Sets status to `translated` (use `--preserve-status` with rich JSON to honor source status) +- Resolves Transloco key references (e.g., `{{t('other.key')}}`, `{{key}}`) by inlining the referenced value; missing references emit a "Missing reference target" warning and circular references emit a "Circular reference detected" warning — both are preserved as literals +- Normalizes Transloco plural/select syntax to ICU format - Overwrites existing values and metadata **Flags Default**: -- `--create-missing`: `true` -- `--update-comments`: `true` -- `--update-tags`: `true` +- `--create-missing`: `true` (applied automatically for migration strategy) +- `--update-comments`: `false` (pass explicitly to enable) +- `--update-tags`: `false` (pass explicitly to enable) **Example**: ```bash -lingo-tracker import --source old-system-fr.json --locale fr --strategy migration +lingo-tracker import --source old-system-fr.json --locale fr --strategy migration \ + --update-comments --update-tags ``` ### update @@ -100,7 +110,7 @@ lingo-tracker import --source old-system-fr.json --locale fr --strategy migratio **Use Case**: Bulk updates to existing translations (maintaining existing status) **Behavior**: -- Updates only existing resources (skips with warning if resource not found) +- Updates only existing resources (skips missing resources; counted in Resources Skipped, not an error) - Preserves existing status (does NOT change to `translated`) - Does NOT create new resources - Useful for fixing typos or updating specific translations @@ -193,7 +203,7 @@ LingoTracker automatically fixes common ICU message format placeholder errors ma **What Gets Reported**: - All auto-fixes are logged in the import summary with before/after values -- Errors for unfixable cases (multiple missing placeholders, malformed syntax) +- Errors for unfixable cases (multiple missing placeholders, malformed syntax) — the resource import fails and is counted in Resources Failed **Example**: ``` @@ -205,7 +215,7 @@ This ensures translations work correctly even when translators accidentally modi ## Import Summary -Every import generates an `import-summary.md` file with detailed change tracking: +Every completed import writes `import-summary.md` to the translations folder (e.g., `src/assets/i18n/import-summary.md`) with detailed change tracking: - Import statistics (resources imported, created, updated, skipped, failed) - Status transitions (e.g., "new → translated", "stale → verified") @@ -214,6 +224,8 @@ Every import generates an `import-summary.md` file with detailed change tracking - Warnings and errors - Detailed change log (first 20 resources) +> **Exit code:** The command exits with code `1` when any resources fail or errors occur. Skipped resources (missing from storage) do not cause a non-zero exit, so CI pipelines will not fail on skips alone. + ### Dry-Run Mode Use `--dry-run` to preview what would be imported without modifying files: @@ -222,13 +234,13 @@ Use `--dry-run` to preview what would be imported without modifying files: lingo-tracker import --source translations-es.xliff --locale es --dry-run ``` -The dry-run summary shows exactly what would happen, using "Would" language to indicate no changes were made. +The dry-run summary shows exactly what would happen, using "Would" language to indicate no changes were made. The summary file is not written in dry-run mode, but the path where it would be written is still printed to the console. ## Interactive Mode If you run `lingo-tracker import` without required options in a terminal, it will launch an interactive wizard to guide you through: -- Source file selection (with file picker/autocomplete) +- Source file path entry (with path validation) - Format auto-detection - Target locale selection (from configured locales) - Collection selection (if multiple exist) diff --git a/docs/features/validate.md b/docs/features/validate.md index 544d1230..45015be4 100644 --- a/docs/features/validate.md +++ b/docs/features/validate.md @@ -1,3 +1,8 @@ +--- +title: Validate +sidebar_position: 4 +--- + # Validate Feature The Validate feature provides a comprehensive translation validation system designed to ensure translation completeness and quality before production deployment. It serves as a quality gate in CI/CD pipelines by checking the status of all translation resources across all configured locales and collections. @@ -29,8 +34,8 @@ lingo-tracker validate [options] ### Exit Codes -- `0` - All validations passed (all resources verified) -- `1` - Validation failures found (new/stale resources or translated without flag) +- `0` - All validations passed (all resources verified or only warnings) +- `1` - Validation failures found, OR configuration errors (config file missing or invalid JSON, no collections configured, no target locales configured) ## Validation Rules @@ -42,6 +47,7 @@ The validate command categorizes resources based on their translation status: | `stale` | ❌ Failure | ❌ Failure | Base value changed, translation out of sync | | `translated` | ❌ Failure | ⚠️ Warning | Has translation but not verified | | `verified` | ✅ Success | ✅ Success | Reviewed and approved | +| *(missing)* | ❌ Failure | ❌ Failure | No status entry for this locale — treated as `new` | ### Validation Philosophy @@ -75,7 +81,8 @@ The validate command categorizes resources based on their translation status: - Base locale (source translations are authoritative by definition) - ICU message format syntax (use separate linting tools) - File structure or JSON validity (handled during resource loading) -- Missing metadata (resources without metadata are skipped with warnings) + +Resources with no status entry for a locale are treated as `new` (failure), not skipped. ## Examples @@ -96,16 +103,28 @@ lingo-tracker validate --allow-translated #### All Verified (Success) ``` -✅ Translation Validation PASSED - -Validation Summary by Locale: - es: - verified: 51 - - fr-ca: - verified: 51 - -Total: 0 failures, 0 warnings +✅ Validation PASSED + +📊 Validation Statistics: +────────────────────────────────────────────────── + Total Resources Validated: 102 + Unique Resource Keys: 51 + Locales Validated: 2 + Collections Validated: 1 + +📈 Status Breakdown: +────────────────────────────────────────────────── + ✅ Verified: 102 + ✏️ Translated: 0 + ⚠️ Stale: 0 + ❌ New: 0 + +────────────────────────────────────────────────── +📋 Summary: + Total Failures: 0 + Total Successes: 102 + +✅ Validation passed successfully! ``` Exit code: `0` @@ -113,36 +132,43 @@ Exit code: `0` #### Mixed Status (Failure) ``` -❌ Translation Validation FAILED - -Validation Summary by Locale: - es: - new: 3 - stale: 2 - translated: 1 - verified: 45 - - fr-ca: - new: 1 - stale: 0 - translated: 2 - verified: 48 - -Failures (6 resources): - es: - - apps.common.buttons.submit (new) - - apps.common.errors.network (new) - - apps.features.dashboard.title (new) - - apps.common.buttons.save (stale) - - apps.features.settings.label (stale) - - apps.common.buttons.cancel (translated) - - fr-ca: - - apps.common.buttons.submit (new) - - apps.features.dashboard.subtitle (translated) - - apps.features.profile.header (translated) - -Total: 6 failures, 0 warnings +❌ Validation FAILED + +📊 Validation Statistics: +────────────────────────────────────────────────── + Total Resources Validated: 102 + Unique Resource Keys: 51 + Locales Validated: 2 + Collections Validated: 1 + +📈 Status Breakdown: +────────────────────────────────────────────────── + ✅ Verified: 93 + ✏️ Translated: 3 + ⚠️ Stale: 2 + ❌ New: 4 + +❌ Failures (9): +────────────────────────────────────────────────── + Locale: es (6 failures) + ❌ [main] apps.common.buttons.submit (new) + ❌ [main] apps.common.errors.network (new) + ❌ [main] apps.features.dashboard.title (new) + ⚠️ [main] apps.common.buttons.save (stale) + ⚠️ [main] apps.features.settings.label (stale) + ✏️ [main] apps.common.buttons.cancel (translated) + + Locale: fr-ca (3 failures) + ❌ [main] apps.common.buttons.submit (new) + ✏️ [main] apps.features.dashboard.subtitle (translated) + ✏️ [main] apps.features.profile.header (translated) + +────────────────────────────────────────────────── +📋 Summary: + Total Failures: 9 + Total Successes: 93 + +❌ Validation failed. Please review the failures above. ``` Exit code: `1` @@ -150,31 +176,40 @@ Exit code: `1` #### With --allow-translated Flag (Warnings) ``` -⚠️ Translation Validation PASSED with warnings - -Validation Summary by Locale: - es: - new: 0 - stale: 0 - translated: 3 - verified: 48 - - fr-ca: - new: 0 - stale: 0 - translated: 1 - verified: 50 - -Warnings (4 resources): - es: - - apps.common.buttons.cancel (translated) - - apps.features.dashboard.subtitle (translated) - - apps.features.profile.header (translated) - - fr-ca: - - apps.common.buttons.apply (translated) - -Total: 0 failures, 4 warnings +✅ Validation PASSED + +📊 Validation Statistics: +────────────────────────────────────────────────── + Total Resources Validated: 102 + Unique Resource Keys: 51 + Locales Validated: 2 + Collections Validated: 1 + +📈 Status Breakdown: +────────────────────────────────────────────────── + ✅ Verified: 98 + ✏️ Translated: 4 + ⚠️ Stale: 0 + ❌ New: 0 + +⚠️ Warnings (4): +────────────────────────────────────────────────── + Resources with "translated" status (not yet verified): + Locale: es (3 warnings) + ✏️ [main] apps.common.buttons.cancel (translated) + ✏️ [main] apps.features.dashboard.subtitle (translated) + ✏️ [main] apps.features.profile.header (translated) + + Locale: fr-ca (1 warnings) + ✏️ [main] apps.common.buttons.apply (translated) + +────────────────────────────────────────────────── +📋 Summary: + Total Failures: 0 + Total Warnings: 4 + Total Successes: 98 + +✅ Validation passed with warnings. ``` Exit code: `0` @@ -247,91 +282,6 @@ jobs: run: pnpm run deploy:staging ``` -### GitLab CI - -```yaml -stages: - - validate - - build - - deploy - -validate-translations: - stage: validate - script: - - lingo-tracker validate - only: - - main - -validate-translations-staging: - stage: validate - script: - - lingo-tracker validate --allow-translated - only: - - develop -``` - -### Jenkins - -```groovy -pipeline { - agent any - - stages { - stage('Validate Translations') { - steps { - sh 'lingo-tracker validate' - } - } - - stage('Build') { - steps { - sh 'pnpm run build' - } - } - - stage('Deploy') { - steps { - sh 'pnpm run deploy' - } - } - } -} -``` - -### CircleCI - -```yaml -version: 2.1 - -jobs: - validate-and-deploy: - docker: - - image: cimg/node:22.16 - steps: - - checkout - - run: - name: Install dependencies - command: pnpm install - - run: - name: Validate translations - command: lingo-tracker validate - - run: - name: Build - command: pnpm run build - - run: - name: Deploy - command: pnpm run deploy - -workflows: - version: 2 - build-and-deploy: - jobs: - - validate-and-deploy: - filters: - branches: - only: main -``` - ### Custom Script Integration ```bash @@ -526,20 +476,23 @@ The validate feature is implemented across two layers: The validate command reuses the existing `loadResourcesFromCollections` utility from the core library, ensuring consistency with export/import operations. -### Status Determination +### Translation Status Semantics -Translation status is determined by examining metadata checksums: +Validate reads pre-computed status values from resource metadata — it does not re-evaluate checksums. The status for each resource/locale pair is determined during resource loading by `loadResourcesFromCollections`. Validate maps a missing status entry to `new` via a null-coalescing fallback. -- **new**: No translation or translation checksum matches base checksum -- **stale**: Base checksum changed since translation was created -- **translated**: Translation exists with non-matching checksums, not verified -- **verified**: Translation exists and marked as verified +The meaning of each status value: + +- **new**: Resource has been added but not yet translated (explicitly stored status) +- **stale**: Base checksum changed since the translation was last updated (source drifted) +- **translated**: Translation exists and matches the current base checksum, but not yet verified +- **verified**: Translation exists and has been explicitly marked as verified + +A missing metadata entry for a locale is coalesced to `new` at validation time (already covered by the *(missing)* row in the Validation Rules table above). ### Performance - **Fast**: Validation only reads metadata, no heavy computation - **Scalable**: Handles projects with 10,000+ resources efficiently -- **Memory-efficient**: Streams through resources, no large in-memory accumulation ## Limitations @@ -554,13 +507,21 @@ Validate always checks ALL collections and ALL target locales. There is no optio ### No Verbose Mode -Unlike export/import commands, validate does not have a `--verbose` flag. Output is always concise, showing only: -- Summary counts by locale -- List of failures -- List of warnings +Unlike export/import commands, validate does not have a `--verbose` flag. Output always includes: +- Statistics (total resources, unique keys, locales, collections validated) +- Status breakdown by count (verified, translated, stale, new) +- Failures grouped by locale (with collection name and status) +- Warnings grouped by locale (when `--allow-translated` is used) +- Summary footer with total counts and final verdict + +Verified resources are not listed individually. **Rationale**: CI logs should be concise. Showing all verified resources adds noise. +### Output Truncation + +Within each locale group, at most 100 failures or warnings are shown. The cap is applied independently per locale — a project with 5 locales could show up to 500 failure lines. When the per-locale limit is exceeded, the output includes `... and N more failures` (or `... and N more warnings` for the warnings section) to indicate additional items. This prevents extremely long CI logs for large projects with many missing translations. + ### No JSON Output Validate only outputs human-readable text. There is no `--json` flag for structured output. diff --git a/docs/getting-started.md b/docs/getting-started.md index 2afff585..2b1b3bdf 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,24 +1,51 @@ +--- +title: Getting Started +sidebar_position: 2 +--- + ## Getting Started Lingo Tracker helps you track, validate, and manage translations across projects. This guide shows how to install the CLI, initialize a project, and add collections. ### Install -Node.js >= 22.16 is required. Install the CLI as a dev dependency in your project: +Node.js >= 22.16 is required. Install the CLI as a dev dependency in your project. + +#### pnpm ```bash pnpm add -D @simoncodes-ca/lingo-tracker +``` + +#### npm + +```bash npm install --save-dev @simoncodes-ca/lingo-tracker +``` + +#### yarn + +```bash yarn add -D @simoncodes-ca/lingo-tracker ``` -Once installed, the use `npx lingo-tracker` command to interact with the CLI. +Once installed, use the `npx lingo-tracker` command to interact with the CLI. + +### Install the Lingo Tracker Skill + +If you use Claude Code (or a compatible AI assistant), install the Lingo Tracker skill to enable guided i18n workflows — detecting hardcoded strings, creating translation resources, and updating components to use Transloco: + +```bash +npx lingo-tracker install-skill +``` + +This writes a skill file to your project that Claude Code picks up automatically. See [`install-skill`](./cli.md#install-skill) in the CLI Reference for details. ### Run the Lingo Tracker App The `lingo-tracker` package ships a built-in API server that hosts the Lingo Tracker web interface. -### Then start the app server: +Then start the app server: ```bash npx lingo-tracker-app @@ -39,7 +66,7 @@ Or set the `LINGO_TRACKER_PORT` environment variable. The `--port` flag takes pr ```json { "scripts": { - "lingo-tracker-app": "lingo-tracker-api --port 4000" + "lingo-tracker-app": "lingo-tracker-app --port 4000" } } ``` @@ -337,4 +364,3 @@ For full details on configuration, ICU handling, and best practices, see the [Au - For managing translation resources and other CLI commands, see the [CLI Reference](./cli.md) - For programmatic access via REST API, see the [API Reference](./api.md) - For setting up machine translation, see the [Auto-Translation Guide](./auto-translation.md) -- To set up an AI assistant skill for your repo (guides Claude Code and similar tools through the i18n workflow), run `lingo-tracker install-skill` — see [`install-skill`](./cli.md#install-skill) in the CLI Reference diff --git a/docs/guides/bundling.md b/docs/guides/bundling.md index e7bf9876..cae0b174 100644 --- a/docs/guides/bundling.md +++ b/docs/guides/bundling.md @@ -1,3 +1,8 @@ +--- +title: Bundling +sidebar_position: 1 +--- + # Bundle Generation Guide This guide provides comprehensive examples and best practices for using LingoTracker's bundle generation feature to create optimized translation files for your applications. @@ -21,7 +26,9 @@ This guide provides comprehensive examples and best practices for using LingoTra ### What Are Bundles? -Bundles are **deployment-ready translation files** generated from LingoTracker's source translations. +LingoTracker stores translations in a structured format optimized for management — version control friendly, metadata-rich, and split across many small files. Your application, however, needs deployment-ready JSON files per locale at runtime. Bundles are that output: **one or more domain-specific translation files** assembled from LingoTracker's source translations. + +A single app might ship a `core` bundle loaded eagerly, an `admin` bundle loaded only for admin users, and a `reports` bundle lazy-loaded on demand. Each bundle is independently configured — you control which collections and keys go into it using key patterns, tags, or both. Tags in particular enable a high degree of customization: you can slice your translations by any cross-cutting concern (feature, audience, environment) regardless of how keys are structured in the folder hierarchy. **Source (LingoTracker)**: ``` @@ -52,6 +59,8 @@ translations/ ## Quick Start +> **Prerequisites**: Complete the [Getting Started](../getting-started.md) guide first. You should already have a `.lingo-tracker.json` with at least one collection configured. + ### 1. Add Bundle Configuration Edit `.lingo-tracker.json`: @@ -95,6 +104,68 @@ src/assets/i18n/ Each file contains hierarchical JSON with all translations for that locale. +> **Want TypeScript type safety?** Add `typeDistFile` to your bundle config and LingoTracker will generate a typed constants file alongside the JSON bundles. See [Bundle Type Generation](../features/bundle-type-generation.md). + +### 4. Add Type-Safe Tokens (Optional) + +Extend the bundle config with `typeDistFile`: + +```json +{ + "bundles": { + "main": { + "bundleName": "{locale}", + "dist": "./src/assets/i18n", + "collections": "All", + "typeDistFile": "./src/generated/main-tokens.ts" + } + } +} +``` + +Running `lingo-tracker bundle` now also generates `src/generated/main-tokens.ts`: + +```typescript +// src/generated/main-tokens.ts (auto-generated — do not edit) +export const MAIN_TOKENS = { + APPS: { + COMMON: { + BUTTONS: { + OK: 'apps.common.buttons.ok', + CANCEL: 'apps.common.buttons.cancel', + APPLY: 'apps.common.buttons.apply', + }, + }, + }, +} as const; + +export type MainTokens = typeof MAIN_TOKENS; +``` + +Use the constants in your components — no more hardcoded string keys: + +```typescript +import { MAIN_TOKENS } from '@/generated/main-tokens'; + +@Component({ + template: ` +

{{ tokens.APPS.COMMON.BUTTONS.OK | transloco }}

+ + ` +}) +export class AppComponent { + readonly tokens = MAIN_TOKENS; +} +``` + +Or pass individual keys directly: + +```typescript +this.translocoService.translate(MAIN_TOKENS.APPS.COMMON.BUTTONS.OK); +``` + +Your IDE will autocomplete available keys, and renaming a key in LingoTracker regenerates the constant — any stale references become compile errors. + --- ## Bundle Configuration @@ -177,29 +248,15 @@ Generate different bundles for different purposes: ### Filename Patterns -The `{locale}` placeholder is replaced with each locale: +The `{locale}` placeholder in `bundleName` is replaced with each locale at generation time: -```json -{ - "bundles": { - "example1": { - "bundleName": "{locale}", // en.json, fr-ca.json - "dist": "./dist/i18n", - "collections": "All" - }, - "example2": { - "bundleName": "app.{locale}", // app.en.json, app.fr-ca.json - "dist": "./dist", - "collections": "All" - }, - "example3": { - "bundleName": "{locale}/main", // en/main.json, fr-ca/main.json - "dist": "./dist/i18n", - "collections": "All" - } - } -} -``` +| `bundleName` | Output files (locales: `en`, `fr-ca`) | +|---|---| +| `{locale}` | `dist/i18n/en.json`, `dist/i18n/fr-ca.json` | +| `app.{locale}` | `dist/app.en.json`, `dist/app.fr-ca.json` | +| `{locale}/main` | `dist/i18n/en/main.json`, `dist/i18n/fr-ca/main.json` | + +The subdirectory form (`{locale}/main`) is useful for frameworks that expect one folder per locale. --- @@ -220,13 +277,11 @@ When multiple collections contribute the same key, merge strategies determine wh "collections": [ { "name": "Common", - "entriesSelectionRules": "All", - "mergeStrategy": "merge" + "entriesSelectionRules": "All" }, { "name": "App", - "entriesSelectionRules": "All", - "mergeStrategy": "merge" + "entriesSelectionRules": "All" } ] } @@ -234,6 +289,8 @@ When multiple collections contribute the same key, merge strategies determine wh } ``` +> `merge` is the default strategy, so you don't need to specify it explicitly. + **Example**: Common collection has: `apps.buttons.ok = "OK"` @@ -526,69 +583,7 @@ export class TranslocoHttpLoader implements TranslocoLoader { export class AppComponent {} ``` ---- - -### react-i18next - -**Bundle Configuration**: -```json -{ - "bundles": { - "react": { - "bundleName": "{locale}/translation", - "dist": "./public/locales", - "collections": "All" - } - } -} -``` - -**Generates**: -``` -public/locales/ -├── en/translation.json -├── fr-ca/translation.json -└── es/translation.json -``` - -**i18next Setup** (`i18n.js`): -```javascript -import i18n from 'i18next'; -import { initReactI18next } from 'react-i18next'; -import HttpBackend from 'i18next-http-backend'; - -i18n - .use(HttpBackend) - .use(initReactI18next) - .init({ - fallbackLng: 'en', - supportedLngs: ['en', 'fr-ca', 'es'], - backend: { - loadPath: '/locales/{{lng}}/{{ns}}.json' - }, - interpolation: { - escapeValue: false - } - }); - -export default i18n; -``` - -**Usage in Components**: -```jsx -import { useTranslation } from 'react-i18next'; - -function App() { - const { t } = useTranslation(); - - return ( -
-

{t('apps.common.title')}

- -
- ); -} -``` +> LingoTracker currently has first-class integration guidance for Angular/Transloco. Other frameworks (React, Vue, etc.) work the same way — configure `bundleName` and `dist` to match where your i18n library expects to load files from. --- @@ -782,6 +777,73 @@ this.translocoService.setActiveLang('en'); this.translocoService.load('admin').subscribe(); ``` +### Tag-Driven Multi-Bundle Split + +Tags let you split a single collection into multiple bundles without relying on key structure. This is useful when translations don't follow a clean folder hierarchy, or when the same key might need to appear in more than one bundle. + +In this example, a single `App` collection is tagged per feature area. Each bundle selects only the keys tagged for it: + +**Tagging your resources** (in LingoTracker UI or via CLI): +- `apps.common.*` keys → tagged `core` +- `apps.admin.*` keys → tagged `admin` +- `apps.reports.*` keys → tagged `reports` + +**Bundle configuration**: + +```json +{ + "bundles": { + "core": { + "bundleName": "core.{locale}", + "dist": "./src/assets/i18n", + "collections": [ + { + "name": "App", + "entriesSelectionRules": [ + { + "matchingPattern": "*", + "matchingTags": ["core"] + } + ] + } + ] + }, + "admin": { + "bundleName": "admin.{locale}", + "dist": "./src/assets/i18n", + "collections": [ + { + "name": "App", + "entriesSelectionRules": [ + { + "matchingPattern": "*", + "matchingTags": ["admin"] + } + ] + } + ] + }, + "reports": { + "bundleName": "reports.{locale}", + "dist": "./src/assets/i18n", + "collections": [ + { + "name": "App", + "entriesSelectionRules": [ + { + "matchingPattern": "*", + "matchingTags": ["reports"] + } + ] + } + ] + } + } +} +``` + +The same approach works for any cross-cutting split: by audience (`public` / `internal`), by feature flag, or by release stage. A key can carry multiple tags, so it can appear in more than one bundle if needed. + ### Environment-Specific Bundles Different bundles for different environments: @@ -814,12 +876,13 @@ Different bundles for different environments: } ``` -Generate specific bundle: +By default `lingo-tracker bundle` generates all configured bundles. Use `--name` to target a single bundle by its key in `.lingo-tracker.json`: + ```bash lingo-tracker bundle --name production ``` -Override token casing from the CLI: +Override token casing for a single bundle run: ```bash lingo-tracker bundle --name core --token-casing camelCase ``` @@ -869,7 +932,11 @@ Different bundles for different tenants: ### Bundled Key Prefixes -Add prefixes to avoid key conflicts: +`bundledKeyPrefix` prepends a namespace segment to every key from a collection before merging. This is useful when two collections have overlapping key structures and you need to keep them separate in the output. + +For example, if both `AppTranslations` and `LibraryTranslations` have a `buttons.ok` key, including both without a prefix would cause a collision (only one value survives). With `bundledKeyPrefix`, each collection's keys live under their own namespace. + +**Example**: ```json { @@ -902,6 +969,8 @@ Add prefixes to avoid key conflicts: ## Troubleshooting +> **Tip**: Run `lingo-tracker bundle --help` for a full list of flags. Add `--verbose` to any bundle command to see detailed output about which keys each collection contributes. + ### Empty Bundle Warning **Problem**: "Bundle 'main' for locale 'en' is empty" @@ -976,17 +1045,19 @@ Add prefixes to avoid key conflicts: ## Summary -Bundle generation is a powerful feature that separates translation management from application deployment: +Bundle generation bridges translation management and application deployment: LingoTracker manages your translations in a structured, version-control-friendly format, and `lingo-tracker bundle` produces the runtime files your app actually loads. -- **Configure once** in `.lingo-tracker.json` -- **Generate anytime** with `lingo-tracker bundle` -- **Integrate seamlessly** with any framework or build tool -- **Filter flexibly** with patterns and tags -- **Customize output** with merge strategies and prefixes +**Recommended next step**: Add bundle generation to your `prebuild` npm script so bundles are always up to date before each build: -For more information: -- [CLI Reference](../cli.md) - Complete command documentation -- [Getting Started](../getting-started.md) - Initial setup guide -- [API Reference](../api.md) - REST API endpoints +```json +{ + "scripts": { + "prebuild": "lingo-tracker bundle" + } +} +``` -**Next Steps**: Add bundle generation to your build pipeline and start deploying optimized translation files! +**Further reading**: +- [Bundle Type Generation](../features/bundle-type-generation.md) — generate TypeScript constants for type-safe translation keys +- [CLI Reference](../cli.md) — full `bundle` command options and flags +- [Getting Started](../getting-started.md) — initial project setup diff --git a/docs/guides/migration.md b/docs/guides/migration.md index f9bd0457..700f10c2 100644 --- a/docs/guides/migration.md +++ b/docs/guides/migration.md @@ -1,3 +1,8 @@ +--- +title: Migration +sidebar_position: 2 +--- + # Migration Guide This guide provides step-by-step instructions for migrating translation resources from other translation management systems to LingoTracker. @@ -78,20 +83,34 @@ Always create a backup of your original translation files before migration: cp -r ./src/i18n ./src/i18n.backup ``` +If something goes wrong, restore with: + +```bash +cp -r ./src/i18n.backup ./src/i18n +``` + ### 3. Choose Migration Strategy LingoTracker's import feature has a dedicated `migration` strategy that: -- Creates new resources (base + translations) -- Resolves Transloco-style key references -- Updates comments and tags by default +- Creates new resources when `--create-missing` is specified +- Resolves Transloco-style key references (`{{t('key')}}`) +- Updates comments and tags when `--update-comments` / `--update-tags` are specified - Sets all imported translations to `translated` status +> **Tip**: Always do a dry run first to preview what will be created before committing to the import: +> ```bash +> lingo-tracker import --source en.json --locale en --strategy migration \ +> --create-missing --dry-run +> ``` + --- ## Migrating from Transloco Transloco is Angular's internationalization library. LingoTracker provides specialized support for Transloco migrations. +> **After completing the steps below**, follow the [Post-Migration Steps](#post-migration-steps) to normalize resources, configure bundles, and test your application. + ### Source Format Transloco typically uses one JSON file per locale: @@ -120,92 +139,24 @@ src/assets/i18n/ } ``` -### Step 1: Export Base Locale with Rich Metadata - -If your Transloco files don't have base values, create a rich JSON export: - -```bash -# Export existing Transloco translations to get structure -lingo-tracker export --format json --locale en --rich --include-base \ - --output ./migration-prep -``` - -This creates `migration-prep/en.json` with rich format that includes base values. - -### Step 2: Prepare Translation Files - -For each target locale, you need to prepare a JSON file with base values. - -**Option A: Transform existing Transloco files manually** - -Create a script to add base values to your Transloco files: - -```javascript -// transform-transloco.js -const fs = require('fs'); - -const baseTranslations = JSON.parse(fs.readFileSync('./src/assets/i18n/en.json', 'utf8')); -const targetTranslations = JSON.parse(fs.readFileSync('./src/assets/i18n/es.json', 'utf8')); - -function addBaseValues(base, target, prefix = '') { - const result = {}; - - for (const [key, value] of Object.entries(target)) { - const fullKey = prefix ? `${prefix}.${key}` : key; - - if (typeof value === 'object' && !Array.isArray(value)) { - // Recurse for nested objects - Object.assign(result, addBaseValues(base[key] || {}, value, fullKey)); - } else { - // Create rich object with base value - result[fullKey] = { - value: value, - baseValue: getNestedValue(base, fullKey.split('.')) || value - }; - } - } - - return result; -} - -function getNestedValue(obj, path) { - return path.reduce((current, key) => current?.[key], obj); -} - -const richFormat = addBaseValues(baseTranslations, targetTranslations); -fs.writeFileSync('./migration/es-rich.json', JSON.stringify(richFormat, null, 2)); - -console.log('Created migration/es-rich.json'); -``` - -Run the script: -```bash -node transform-transloco.js -``` - -**Option B: Use hierarchical format with manual base values** +### Step 1: Import Base Locale -Simply use your existing Transloco JSON files and add base values during import: - -1. Keep your Transloco files as-is -2. Import with `--strategy migration` -3. LingoTracker will use the base locale file for base values - -### Step 3: Import Base Locale - -Import the base locale first to create the resource structure: +Import the base locale first to create the resource structure. If you have multiple collections, add `--collection `: ```bash lingo-tracker import \ --source ./src/assets/i18n/en.json \ --locale en \ --strategy migration \ + --create-missing \ + --update-comments \ + --update-tags \ --verbose ``` -**Note**: When importing into the base locale during migration, LingoTracker creates resources with the base locale value. This is a special case only for the `migration` strategy. +**Note**: Importing into the base locale is only supported with the `migration` strategy. It creates resources with the base locale value set from the JSON values. -### Step 4: Import Target Locales +### Step 2: Import Target Locales Import each target locale: @@ -215,6 +166,9 @@ lingo-tracker import \ --source ./src/assets/i18n/es.json \ --locale es \ --strategy migration \ + --create-missing \ + --update-comments \ + --update-tags \ --verbose # Import French @@ -222,17 +176,23 @@ lingo-tracker import \ --source ./src/assets/i18n/fr.json \ --locale fr \ --strategy migration \ - --verbose + --create-missing \ + --update-comments \ + --update-tags # Import German lingo-tracker import \ --source ./src/assets/i18n/de.json \ --locale de \ --strategy migration \ - --verbose + --create-missing \ + --update-comments \ + --update-tags ``` -### Step 5: Handle Transloco References +> **If your target locale files are missing base values**, you can add them with a transformation script before importing. See [Migrating from Other Systems > Generic JSON](#from-json-files-generic) for an example transform. + +### Step 3: Handle Transloco References If your Transloco files use references like `{{t('other.key')}}`, LingoTracker automatically resolves them during migration: @@ -254,11 +214,12 @@ If your Transloco files use references like `{{t('other.key')}}`, LingoTracker a This happens automatically with the `migration` strategy. -### Step 6: Verify Migration +### Step 4: Verify Migration -Check the import summary for statistics and warnings: +Check the import summary — the exact path is printed at the end of each import command output (typically `{translationsFolder}/import-summary.md`): ```bash +# Example — adjust path to match your translationsFolder config cat translations/import-summary.md ``` @@ -268,7 +229,7 @@ Verify a few resources were created correctly: cat translations/common/buttons/resource_entries.json ``` -### Step 7: Update Transloco Configuration +### Step 5: Update Transloco Configuration After migration, update your Transloco loader to use LingoTracker bundles: @@ -308,6 +269,8 @@ loader: TranslocoHttpLoader // Loads from src/assets/i18n i18next is a popular internationalization framework for JavaScript. LingoTracker can import i18next JSON files directly. +> **After completing the steps below**, follow the [Post-Migration Steps](#post-migration-steps) to normalize resources, configure bundles, and test your application. + ### Source Format i18next typically organizes translations by namespace: @@ -417,13 +380,16 @@ node combine-namespaces.js ### Step 2: Import Base Locale -Import the base locale (usually English): +Import the base locale (usually English). If you have multiple collections, add `--collection `: ```bash lingo-tracker import \ --source ./migration/en.json \ --locale en \ --strategy migration \ + --create-missing \ + --update-comments \ + --update-tags \ --verbose ``` @@ -436,13 +402,19 @@ Import each target locale: lingo-tracker import \ --source ./migration/es.json \ --locale es \ - --strategy migration + --strategy migration \ + --create-missing \ + --update-comments \ + --update-tags # Import French lingo-tracker import \ --source ./migration/fr.json \ --locale fr \ - --strategy migration + --strategy migration \ + --create-missing \ + --update-comments \ + --update-tags ``` ### Step 4: Update i18next Configuration @@ -529,12 +501,14 @@ Create a transformation script to convert your format to LingoTracker's expected lingo-tracker import \ --source ./transformed-en.json \ --locale en \ - --strategy migration + --strategy migration \ + --create-missing lingo-tracker import \ --source ./transformed-es.json \ --locale es \ - --strategy migration + --strategy migration \ + --create-missing ``` ### From XLIFF Files @@ -559,6 +533,7 @@ lingo-tracker import \ --source ./es.xliff \ --locale es \ --strategy migration \ + --create-missing \ --verbose ``` @@ -612,7 +587,8 @@ fs.writeFileSync('./es-transformed.json', JSON.stringify(transformed, null, 2)); lingo-tracker import \ --source ./es-transformed.json \ --locale es \ - --strategy migration + --strategy migration \ + --create-missing ``` ### From CSV Files @@ -667,9 +643,9 @@ buttons.ok,OK,Aceptar,OK,OK #### Step 2: Import ```bash -lingo-tracker import --source ./es.json --locale es --strategy migration -lingo-tracker import --source ./fr.json --locale fr --strategy migration -lingo-tracker import --source ./de.json --locale de --strategy migration +lingo-tracker import --source ./es.json --locale es --strategy migration --create-missing +lingo-tracker import --source ./fr.json --locale fr --strategy migration --create-missing +lingo-tracker import --source ./de.json --locale de --strategy migration --create-missing ``` --- @@ -678,9 +654,10 @@ lingo-tracker import --source ./de.json --locale de --strategy migration ### 1. Verify Import Summary -Check the import summary for each locale: +The import command prints the summary file path at the end of its output. Open it to check each locale import: ```bash +# Path depends on your translationsFolder config — check the import output cat translations/import-summary.md ``` @@ -708,6 +685,8 @@ Export resources with `new` or `stale` status to identify missing translations: lingo-tracker export --format json --status new,stale --output ./review ``` +If you have multiple collections, add `--collection ` to target a specific one. + ### 4. Configure Bundles Set up bundle generation for your framework: @@ -883,12 +862,12 @@ cat translations/path/to/resource/resource_entries.json ### Import Summary Shows Skipped Resources -**Cause**: Using wrong strategy. Default `translation-service` strategy doesn't create new resources. +**Cause**: Using wrong strategy or missing `--create-missing`. Default `translation-service` strategy doesn't create new resources. -**Solution**: Use `--strategy migration` for migration imports: +**Solution**: Use `--strategy migration --create-missing` for migration imports: ```bash -lingo-tracker import --source file.json --locale es --strategy migration +lingo-tracker import --source file.json --locale es --strategy migration --create-missing ``` --- @@ -897,9 +876,9 @@ lingo-tracker import --source file.json --locale es --strategy migration Migrating to LingoTracker involves: -1. **Export** from source system (or use existing files) -2. **Transform** to JSON or XLIFF format -3. **Import** with `--strategy migration` +1. **Prepare** source files (transform format if needed) +2. **Dry run** with `--dry-run` to preview what will be created +3. **Import** with `--strategy migration --create-missing` 4. **Normalize** to add missing locale entries 5. **Configure** bundles for your framework 6. **Test** thoroughly before removing old files @@ -907,16 +886,19 @@ Migrating to LingoTracker involves: ### Quick Reference ```bash -# Migration workflow -lingo-tracker import --source en.json --locale en --strategy migration -lingo-tracker import --source es.json --locale es --strategy migration -lingo-tracker import --source fr.json --locale fr --strategy migration +# Migration workflow (base locale first, then target locales) +lingo-tracker import --source en.json --locale en --strategy migration \ + --create-missing --update-comments --update-tags +lingo-tracker import --source es.json --locale es --strategy migration \ + --create-missing --update-comments --update-tags +lingo-tracker import --source fr.json --locale fr --strategy migration \ + --create-missing --update-comments --update-tags # Post-migration lingo-tracker normalize --all lingo-tracker bundle -# Verify +# Verify (path printed at end of each import command) cat translations/import-summary.md ``` diff --git a/libs/core/src/collections-manager/add-locale-to-collection.spec.ts b/libs/core/src/collections-manager/add-locale-to-collection.spec.ts new file mode 100644 index 00000000..6f6fdfb9 --- /dev/null +++ b/libs/core/src/collections-manager/add-locale-to-collection.spec.ts @@ -0,0 +1,185 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import fs from 'fs'; +import path from 'path'; +import { addLocaleToCollection } from './add-locale-to-collection'; +import { calculateChecksum } from '../resource/checksum'; +import type { ResourceEntries } from '../resource/resource-entry'; +import type { TrackerMetadata } from '../resource/tracker-metadata'; +import type { SafeAny } from '../constants'; +import { setupMockFs, makeBaseConfig } from './locale-spec-helpers'; + +vi.mock('fs'); + +const CWD = '/test'; +const CONFIG_PATH = path.join(CWD, '.lingo-tracker.json'); +const TRANSLATIONS_FOLDER = path.join(CWD, 'src/i18n'); + +function makeConfig(overrides: SafeAny = {}) { + return makeBaseConfig(overrides); +} + +describe('addLocaleToCollection', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('adds locale to config and backfills resource entries', async () => { + const entries: ResourceEntries = { + ok: { source: 'OK', fr: 'OK' }, + }; + const meta: TrackerMetadata = { + ok: { + en: { checksum: calculateChecksum('OK') }, + fr: { checksum: calculateChecksum('OK'), baseChecksum: calculateChecksum('OK'), status: 'new' }, + }, + }; + + setupMockFs({ + [CONFIG_PATH]: { type: 'file', content: JSON.stringify(makeConfig()) }, + [TRANSLATIONS_FOLDER]: { type: 'directory', children: ['resource_entries.json', 'tracker_meta.json'] }, + [path.join(TRANSLATIONS_FOLDER, 'resource_entries.json')]: { type: 'file', content: JSON.stringify(entries) }, + [path.join(TRANSLATIONS_FOLDER, 'tracker_meta.json')]: { type: 'file', content: JSON.stringify(meta) }, + }); + + const result = await addLocaleToCollection('main', 'de', { cwd: CWD }); + + expect(result.message).toBe('Locale "de" added to collection "main" successfully'); + expect(result.entriesBackfilled).toBe(1); + expect(result.filesUpdated).toBe(1); + + const writeCalls = vi.mocked(fs.writeFileSync).mock.calls; + // First call: config file + const configWrite = JSON.parse(writeCalls[0][1] as string); + expect(configWrite.collections.main.locales).toContain('de'); + + // Second call: resource_entries.json — de entry should be source value + const entriesWrite = JSON.parse(writeCalls[1][1] as string); + expect(entriesWrite.ok.de).toBe('OK'); + + // Third call: tracker_meta.json — de metadata should be status 'new' + const metaWrite = JSON.parse(writeCalls[2][1] as string); + expect(metaWrite.ok.de).toMatchObject({ + checksum: calculateChecksum('OK'), + baseChecksum: calculateChecksum('OK'), + status: 'new', + }); + }); + + it('copies global locales into collection when collection has no locales override', async () => { + setupMockFs({ + [CONFIG_PATH]: { type: 'file', content: JSON.stringify(makeConfig()) }, + [TRANSLATIONS_FOLDER]: { type: 'directory', children: [] }, + }); + + const result = await addLocaleToCollection('main', 'de', { cwd: CWD }); + + expect(result.message).toContain('de'); + + const configWriteCall = vi.mocked(fs.writeFileSync).mock.calls[0]; + const writtenConfig = JSON.parse(configWriteCall[1] as string); + // Should have copied global locales AND added de + expect(writtenConfig.collections.main.locales).toEqual(['en', 'fr', 'de']); + }); + + it('does not copy global locales when collection already has explicit locales', async () => { + const config = makeConfig({ + locales: ['en', 'fr'], + collections: { + main: { translationsFolder: 'src/i18n', locales: ['en', 'fr'] }, + }, + }); + + setupMockFs({ + [CONFIG_PATH]: { type: 'file', content: JSON.stringify(config) }, + [TRANSLATIONS_FOLDER]: { type: 'directory', children: [] }, + }); + + await addLocaleToCollection('main', 'de', { cwd: CWD }); + + const configWriteCall = vi.mocked(fs.writeFileSync).mock.calls[0]; + const writtenConfig = JSON.parse(configWriteCall[1] as string); + expect(writtenConfig.collections.main.locales).toEqual(['en', 'fr', 'de']); + }); + + it('handles empty translations folder gracefully (no resource files)', async () => { + setupMockFs({ + [CONFIG_PATH]: { type: 'file', content: JSON.stringify(makeConfig()) }, + [TRANSLATIONS_FOLDER]: { type: 'directory', children: [] }, + }); + + const result = await addLocaleToCollection('main', 'de', { cwd: CWD }); + + expect(result.entriesBackfilled).toBe(0); + expect(result.filesUpdated).toBe(0); + }); + + it('handles non-existent translations folder gracefully', async () => { + setupMockFs({ + [CONFIG_PATH]: { type: 'file', content: JSON.stringify(makeConfig()) }, + // translations folder not in mockFs + }); + + const result = await addLocaleToCollection('main', 'de', { cwd: CWD }); + + expect(result.entriesBackfilled).toBe(0); + expect(result.filesUpdated).toBe(0); + }); + + it('throws when locale already exists in collection', async () => { + setupMockFs({ + [CONFIG_PATH]: { type: 'file', content: JSON.stringify(makeConfig()) }, + }); + + await expect(addLocaleToCollection('main', 'fr', { cwd: CWD })).rejects.toThrow( + 'Locale "fr" already exists in collection "main"', + ); + }); + + it('throws when trying to add the base locale', async () => { + setupMockFs({ + [CONFIG_PATH]: { type: 'file', content: JSON.stringify(makeConfig()) }, + }); + + await expect(addLocaleToCollection('main', 'en', { cwd: CWD })).rejects.toThrow( + 'Cannot add or remove the base locale "en"', + ); + }); + + it('throws when collection does not exist', async () => { + setupMockFs({ + [CONFIG_PATH]: { type: 'file', content: JSON.stringify(makeConfig()) }, + }); + + await expect(addLocaleToCollection('nonexistent', 'de', { cwd: CWD })).rejects.toThrow( + 'Collection "nonexistent" not found', + ); + }); + + it('throws when locale format is invalid', async () => { + setupMockFs({ + [CONFIG_PATH]: { type: 'file', content: JSON.stringify(makeConfig()) }, + }); + + await expect(addLocaleToCollection('main', 'not-valid-123', { cwd: CWD })).rejects.toThrow('Invalid locale format'); + }); + + it('uses collection-level baseLocale when blocking base locale add', async () => { + const config = makeConfig({ + collections: { + main: { translationsFolder: 'src/i18n', baseLocale: 'fr' }, + }, + }); + + setupMockFs({ + [CONFIG_PATH]: { type: 'file', content: JSON.stringify(config) }, + }); + + await expect(addLocaleToCollection('main', 'fr', { cwd: CWD })).rejects.toThrow( + 'Cannot add or remove the base locale "fr"', + ); + }); +}); diff --git a/libs/core/src/collections-manager/add-locale-to-collection.ts b/libs/core/src/collections-manager/add-locale-to-collection.ts new file mode 100644 index 00000000..d2e6b8e4 --- /dev/null +++ b/libs/core/src/collections-manager/add-locale-to-collection.ts @@ -0,0 +1,124 @@ +import * as path from 'node:path'; +import * as fs from 'node:fs'; +import { validateLocale } from '@simoncodes-ca/domain'; +import { updateConfig } from '../lib/config/config-file-operations'; +import { walkFolders } from '../lib/normalize/iterative-folder-walker'; +import { readResourceEntries, readTrackerMetadata, writeJsonFile } from '../lib/file-io/json-file-operations'; +import { calculateChecksum } from '../resource/checksum'; +import { ErrorMessages } from '../lib/errors/error-messages'; +import { RESOURCE_ENTRIES_FILENAME, TRACKER_META_FILENAME } from '../constants'; + +export interface AddLocaleToCollectionOptions { + readonly cwd?: string; +} + +export interface AddLocaleToCollectionResult { + readonly message: string; + readonly entriesBackfilled: number; + readonly filesUpdated: number; +} + +export async function addLocaleToCollection( + collectionName: string, + locale: string, + options: AddLocaleToCollectionOptions = {}, +): Promise { + const cwd = options.cwd ?? process.cwd(); + + validateLocale(locale); + + const updatedConfig = updateConfig((config) => { + if (!config.collections?.[collectionName]) { + throw new Error(ErrorMessages.collectionNotFound(collectionName)); + } + + const collection = config.collections[collectionName]; + const baseLocale = collection.baseLocale ?? config.baseLocale; + + if (locale === baseLocale) { + throw new Error(ErrorMessages.cannotModifyBaseLocale(locale)); + } + + const effectiveLocales = collection.locales ?? config.locales ?? []; + + if (effectiveLocales.includes(locale)) { + throw new Error(ErrorMessages.localeAlreadyExists(locale, collectionName)); + } + + const newLocales = [...effectiveLocales, locale]; + + return { + ...config, + collections: { + ...config.collections, + [collectionName]: { + ...collection, + locales: newLocales, + }, + }, + }; + }, cwd); + + const collection = updatedConfig.collections[collectionName]; + const translationsFolderPath = path.resolve(cwd, collection.translationsFolder); + + let entriesBackfilled = 0; + let filesUpdated = 0; + + for (const visit of walkFolders(translationsFolderPath)) { + const resourceEntriesPath = path.join(visit.absolutePath, RESOURCE_ENTRIES_FILENAME); + const trackerMetaPath = path.join(visit.absolutePath, TRACKER_META_FILENAME); + + if (!fs.existsSync(resourceEntriesPath)) continue; + + const resourceEntries = readResourceEntries(resourceEntriesPath); + + const trackerMetadata = readTrackerMetadata(trackerMetaPath, {}); + + let folderModified = false; + + for (const entryKey of Object.keys(resourceEntries)) { + const entry = resourceEntries[entryKey]; + + if (typeof entry !== 'object' || entry === null || typeof entry.source !== 'string') { + continue; + } + + if (typeof entry[locale] === 'string') { + continue; + } + + // Seed the new locale with the base (source) value and status 'new' — + // this matches the convention used by normalizeEntry/ensureLocaleEntryExists, + // which also seeds missing locales with baseValue and marks them 'new'. + const baseValue = entry.source; + const checksum = calculateChecksum(baseValue); + + entry[locale] = baseValue; + + if (!trackerMetadata[entryKey]) { + trackerMetadata[entryKey] = {}; + } + trackerMetadata[entryKey][locale] = { + checksum, + baseChecksum: checksum, + status: 'new', + }; + + entriesBackfilled++; + folderModified = true; + } + + if (folderModified) { + writeJsonFile({ filePath: resourceEntriesPath, data: resourceEntries }); + writeJsonFile({ filePath: trackerMetaPath, data: trackerMetadata }); + filesUpdated++; + } + } + + return { + message: `Locale "${locale}" added to collection "${collectionName}" successfully`, + entriesBackfilled, + filesUpdated, + }; +} diff --git a/libs/core/src/collections-manager/index.ts b/libs/core/src/collections-manager/index.ts index ef860e15..676a72e4 100644 --- a/libs/core/src/collections-manager/index.ts +++ b/libs/core/src/collections-manager/index.ts @@ -1,3 +1,5 @@ export * from './delete-collection-by-name'; export * from './add-collection'; export * from './update-collection'; +export * from './add-locale-to-collection'; +export * from './remove-locale-from-collection'; diff --git a/libs/core/src/collections-manager/locale-spec-helpers.spec.ts b/libs/core/src/collections-manager/locale-spec-helpers.spec.ts new file mode 100644 index 00000000..8662e2ef --- /dev/null +++ b/libs/core/src/collections-manager/locale-spec-helpers.spec.ts @@ -0,0 +1,17 @@ +import { describe, it, expect } from 'vitest'; +import { makeBaseConfig } from './locale-spec-helpers'; + +describe('locale-spec-helpers', () => { + it('makeBaseConfig returns the expected shape', () => { + const config = makeBaseConfig(); + expect(config).toMatchObject({ + baseLocale: 'en', + locales: ['en', 'fr'], + collections: { + main: { + translationsFolder: 'src/i18n', + }, + }, + }); + }); +}); diff --git a/libs/core/src/collections-manager/locale-spec-helpers.ts b/libs/core/src/collections-manager/locale-spec-helpers.ts new file mode 100644 index 00000000..fb40f4ae --- /dev/null +++ b/libs/core/src/collections-manager/locale-spec-helpers.ts @@ -0,0 +1,58 @@ +import { vi } from 'vitest'; +import * as fs from 'fs'; +import * as path from 'path'; +import type { SafeAny } from '../constants'; + +export interface MockFile { + type: 'file' | 'directory'; + content?: string; + children?: string[]; +} + +export function setupMockFs(mockFs: Record): void { + vi.mocked(fs.existsSync).mockImplementation((p: fs.PathLike) => (p as string) in mockFs); + + vi.mocked(fs.readdirSync).mockImplementation(((p: fs.PathLike, opts?: SafeAny) => { + const entry = mockFs[p as string]; + if (!entry || entry.type !== 'directory') return []; + const childNames = entry.children ?? []; + if (opts && typeof opts === 'object' && (opts as { withFileTypes?: boolean }).withFileTypes) { + return childNames.map((name) => { + const childPath = path.join(p as string, name); + const isDir = mockFs[childPath]?.type === 'directory'; + return { + name, + isDirectory: () => isDir, + isFile: () => !isDir, + isSymbolicLink: () => false, + isBlockDevice: () => false, + isCharacterDevice: () => false, + isFIFO: () => false, + isSocket: () => false, + } as unknown as fs.Dirent; + }); + } + return childNames as unknown as fs.Dirent[]; + }) as SafeAny); + + vi.mocked(fs.readFileSync).mockImplementation((p: fs.PathOrFileDescriptor) => { + const entry = mockFs[p as string]; + if (!entry || entry.type !== 'file') throw new Error(`ENOENT: ${p}`); + return entry.content ?? ''; + }); + + vi.mocked(fs.writeFileSync).mockImplementation(() => undefined); +} + +export function makeBaseConfig(overrides: SafeAny = {}): SafeAny { + return { + baseLocale: 'en', + locales: ['en', 'fr'], + collections: { + main: { + translationsFolder: 'src/i18n', + }, + }, + ...overrides, + }; +} diff --git a/libs/core/src/collections-manager/remove-locale-from-collection.spec.ts b/libs/core/src/collections-manager/remove-locale-from-collection.spec.ts new file mode 100644 index 00000000..54efff07 --- /dev/null +++ b/libs/core/src/collections-manager/remove-locale-from-collection.spec.ts @@ -0,0 +1,193 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import fs from 'fs'; +import path from 'path'; +import { removeLocaleFromCollection } from './remove-locale-from-collection'; +import { calculateChecksum } from '../resource/checksum'; +import type { ResourceEntries } from '../resource/resource-entry'; +import type { TrackerMetadata } from '../resource/tracker-metadata'; +import type { SafeAny } from '../constants'; +import { setupMockFs, makeBaseConfig } from './locale-spec-helpers'; + +vi.mock('fs'); + +const CWD = '/test'; +const CONFIG_PATH = path.join(CWD, '.lingo-tracker.json'); +const TRANSLATIONS_FOLDER = path.join(CWD, 'src/i18n'); + +function makeConfig(overrides: SafeAny = {}) { + return makeBaseConfig({ + locales: ['en', 'fr', 'de'], + ...overrides, + }); +} + +describe('removeLocaleFromCollection', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('removes locale from config and purges resource entries', async () => { + const entries: ResourceEntries = { + ok: { source: 'OK', fr: 'OK FR', de: 'OK DE' }, + }; + const meta: TrackerMetadata = { + ok: { + en: { checksum: calculateChecksum('OK') }, + fr: { checksum: calculateChecksum('OK FR'), baseChecksum: calculateChecksum('OK'), status: 'translated' }, + de: { checksum: calculateChecksum('OK DE'), baseChecksum: calculateChecksum('OK'), status: 'translated' }, + }, + }; + + setupMockFs({ + [CONFIG_PATH]: { type: 'file', content: JSON.stringify(makeConfig()) }, + [TRANSLATIONS_FOLDER]: { type: 'directory', children: ['resource_entries.json', 'tracker_meta.json'] }, + [path.join(TRANSLATIONS_FOLDER, 'resource_entries.json')]: { type: 'file', content: JSON.stringify(entries) }, + [path.join(TRANSLATIONS_FOLDER, 'tracker_meta.json')]: { type: 'file', content: JSON.stringify(meta) }, + }); + + const result = await removeLocaleFromCollection('main', 'fr', { cwd: CWD }); + + expect(result.message).toBe('Locale "fr" removed from collection "main" successfully'); + expect(result.entriesPurged).toBe(1); + expect(result.filesUpdated).toBe(1); + + const writeCalls = vi.mocked(fs.writeFileSync).mock.calls; + + // First write: updated config (fr removed from locales) + const configWrite = JSON.parse(writeCalls[0][1] as string); + expect(configWrite.collections.main.locales).not.toContain('fr'); + expect(configWrite.collections.main.locales).toContain('de'); + + // Second write: updated resource_entries.json (fr key removed) + const entriesWrite = JSON.parse(writeCalls[1][1] as string); + expect(entriesWrite.ok.fr).toBeUndefined(); + expect(entriesWrite.ok.de).toBe('OK DE'); + + // Third write: updated tracker_meta.json (fr metadata removed) + const metaWrite = JSON.parse(writeCalls[2][1] as string); + expect(metaWrite.ok.fr).toBeUndefined(); + expect(metaWrite.ok.de).toBeDefined(); + }); + + it('copies global locales into collection when collection has no locales override', async () => { + setupMockFs({ + [CONFIG_PATH]: { type: 'file', content: JSON.stringify(makeConfig()) }, + [TRANSLATIONS_FOLDER]: { type: 'directory', children: [] }, + }); + + const result = await removeLocaleFromCollection('main', 'fr', { cwd: CWD }); + + expect(result.message).toContain('fr'); + + const configWriteCall = vi.mocked(fs.writeFileSync).mock.calls[0]; + const writtenConfig = JSON.parse(configWriteCall[1] as string); + // Should have copied global locales and removed fr + expect(writtenConfig.collections.main.locales).toEqual(['en', 'de']); + }); + + it('allows removing the last non-base locale (monolingual collection)', async () => { + const config = makeConfig({ + locales: ['en', 'fr'], + collections: { + main: { translationsFolder: 'src/i18n', locales: ['en', 'fr'] }, + }, + }); + + setupMockFs({ + [CONFIG_PATH]: { type: 'file', content: JSON.stringify(config) }, + [TRANSLATIONS_FOLDER]: { type: 'directory', children: [] }, + }); + + const result = await removeLocaleFromCollection('main', 'fr', { cwd: CWD }); + + expect(result.message).toContain('fr'); + + const configWriteCall = vi.mocked(fs.writeFileSync).mock.calls[0]; + const writtenConfig = JSON.parse(configWriteCall[1] as string); + expect(writtenConfig.collections.main.locales).toEqual(['en']); + }); + + it('handles empty translations folder gracefully (no resource files)', async () => { + setupMockFs({ + [CONFIG_PATH]: { type: 'file', content: JSON.stringify(makeConfig()) }, + [TRANSLATIONS_FOLDER]: { type: 'directory', children: [] }, + }); + + const result = await removeLocaleFromCollection('main', 'fr', { cwd: CWD }); + + expect(result.entriesPurged).toBe(0); + expect(result.filesUpdated).toBe(0); + }); + + it('handles non-existent translations folder gracefully', async () => { + setupMockFs({ + [CONFIG_PATH]: { type: 'file', content: JSON.stringify(makeConfig()) }, + // no translations folder + }); + + const result = await removeLocaleFromCollection('main', 'fr', { cwd: CWD }); + + expect(result.entriesPurged).toBe(0); + expect(result.filesUpdated).toBe(0); + }); + + it('throws when locale does not exist in collection', async () => { + setupMockFs({ + [CONFIG_PATH]: { type: 'file', content: JSON.stringify(makeConfig()) }, + }); + + await expect(removeLocaleFromCollection('main', 'ja', { cwd: CWD })).rejects.toThrow( + 'Locale "ja" not found in collection "main"', + ); + }); + + it('throws when trying to remove the base locale', async () => { + setupMockFs({ + [CONFIG_PATH]: { type: 'file', content: JSON.stringify(makeConfig()) }, + }); + + await expect(removeLocaleFromCollection('main', 'en', { cwd: CWD })).rejects.toThrow( + 'Cannot add or remove the base locale "en"', + ); + }); + + it('throws when collection does not exist', async () => { + setupMockFs({ + [CONFIG_PATH]: { type: 'file', content: JSON.stringify(makeConfig()) }, + }); + + await expect(removeLocaleFromCollection('nonexistent', 'fr', { cwd: CWD })).rejects.toThrow( + 'Collection "nonexistent" not found', + ); + }); + + it('throws when locale format is invalid', async () => { + setupMockFs({ + [CONFIG_PATH]: { type: 'file', content: JSON.stringify(makeConfig()) }, + }); + + await expect(removeLocaleFromCollection('main', 'not-valid-123', { cwd: CWD })).rejects.toThrow( + 'Invalid locale format', + ); + }); + + it('uses collection-level baseLocale when blocking base locale removal', async () => { + const config = makeConfig({ + collections: { + main: { translationsFolder: 'src/i18n', baseLocale: 'fr', locales: ['fr', 'de'] }, + }, + }); + + setupMockFs({ + [CONFIG_PATH]: { type: 'file', content: JSON.stringify(config) }, + }); + + await expect(removeLocaleFromCollection('main', 'fr', { cwd: CWD })).rejects.toThrow( + 'Cannot add or remove the base locale "fr"', + ); + }); +}); diff --git a/libs/core/src/collections-manager/remove-locale-from-collection.ts b/libs/core/src/collections-manager/remove-locale-from-collection.ts new file mode 100644 index 00000000..288f23fc --- /dev/null +++ b/libs/core/src/collections-manager/remove-locale-from-collection.ts @@ -0,0 +1,116 @@ +import * as path from 'node:path'; +import * as fs from 'node:fs'; +import { validateLocale } from '@simoncodes-ca/domain'; +import { updateConfig } from '../lib/config/config-file-operations'; +import { walkFolders } from '../lib/normalize/iterative-folder-walker'; +import { readResourceEntries, readTrackerMetadata, writeJsonFile } from '../lib/file-io/json-file-operations'; +import { ErrorMessages } from '../lib/errors/error-messages'; +import { RESOURCE_ENTRIES_FILENAME, TRACKER_META_FILENAME } from '../constants'; + +export interface RemoveLocaleFromCollectionOptions { + readonly cwd?: string; +} + +export interface RemoveLocaleFromCollectionResult { + readonly message: string; + readonly entriesPurged: number; + readonly filesUpdated: number; +} + +export async function removeLocaleFromCollection( + collectionName: string, + locale: string, + options: RemoveLocaleFromCollectionOptions = {}, +): Promise { + const cwd = options.cwd ?? process.cwd(); + + validateLocale(locale); + + const updatedConfig = updateConfig((config) => { + if (!config.collections?.[collectionName]) { + throw new Error(ErrorMessages.collectionNotFound(collectionName)); + } + + const collection = config.collections[collectionName]; + const baseLocale = collection.baseLocale ?? config.baseLocale; + + if (locale === baseLocale) { + throw new Error(ErrorMessages.cannotModifyBaseLocale(locale)); + } + + const effectiveLocales = collection.locales ?? config.locales ?? []; + + if (!effectiveLocales.includes(locale)) { + throw new Error(ErrorMessages.localeNotFound(locale, collectionName)); + } + + const newLocales = effectiveLocales.filter((l) => l !== locale); + + return { + ...config, + collections: { + ...config.collections, + [collectionName]: { + ...collection, + locales: newLocales, + }, + }, + }; + }, cwd); + + const collection = updatedConfig.collections[collectionName]; + const translationsFolderPath = path.resolve(cwd, collection.translationsFolder); + + let entriesPurged = 0; + let filesUpdated = 0; + + for (const visit of walkFolders(translationsFolderPath)) { + const resourceEntriesPath = path.join(visit.absolutePath, RESOURCE_ENTRIES_FILENAME); + const trackerMetaPath = path.join(visit.absolutePath, TRACKER_META_FILENAME); + + if (!fs.existsSync(resourceEntriesPath)) continue; + + const resourceEntries = readResourceEntries(resourceEntriesPath); + + const trackerMetadata = readTrackerMetadata(trackerMetaPath, {}); + + let folderModified = false; + + for (const entryKey of Object.keys(resourceEntries)) { + const entry = resourceEntries[entryKey]; + + if (typeof entry !== 'object' || entry === null) { + continue; + } + + let entryModified = false; + + if (locale in entry) { + delete entry[locale]; + entryModified = true; + } + + if (trackerMetadata[entryKey] && locale in trackerMetadata[entryKey]) { + delete trackerMetadata[entryKey][locale]; + entryModified = true; + } + + if (entryModified) { + entriesPurged++; + folderModified = true; + } + } + + if (folderModified) { + writeJsonFile({ filePath: resourceEntriesPath, data: resourceEntries }); + writeJsonFile({ filePath: trackerMetaPath, data: trackerMetadata }); + filesUpdated++; + } + } + + return { + message: `Locale "${locale}" removed from collection "${collectionName}" successfully`, + entriesPurged, + filesUpdated, + }; +} diff --git a/libs/core/src/config/translation-config.ts b/libs/core/src/config/translation-config.ts index 83369b22..5fb27a52 100644 --- a/libs/core/src/config/translation-config.ts +++ b/libs/core/src/config/translation-config.ts @@ -7,4 +7,8 @@ export interface TranslationConfig { readonly enabled: boolean; readonly provider: string; readonly apiKeyEnv: string; + /** Number of resources to send per API batch when translating a full locale. Defaults to 5. */ + readonly batchSize?: number; + /** Milliseconds to wait between batches to avoid rate-limit errors. Defaults to 1000. */ + readonly delayMs?: number; } diff --git a/libs/core/src/lib/errors/error-messages.ts b/libs/core/src/lib/errors/error-messages.ts index b508b171..d3d5019b 100644 --- a/libs/core/src/lib/errors/error-messages.ts +++ b/libs/core/src/lib/errors/error-messages.ts @@ -24,5 +24,12 @@ export const ErrorMessages = { collectionAlreadyExists: (name: string) => `Collection "${name}" already exists`, + localeAlreadyExists: (locale: string, collection: string) => + `Locale "${locale}" already exists in collection "${collection}"`, + + localeNotFound: (locale: string, collection: string) => `Locale "${locale}" not found in collection "${collection}"`, + + cannotModifyBaseLocale: (locale: string) => `Cannot add or remove the base locale "${locale}"`, + invalidKey: (key: string, reason: string) => `Invalid resource key "${key}": ${reason}`, } as const; diff --git a/libs/core/src/lib/translation/index.ts b/libs/core/src/lib/translation/index.ts index f6ad4b6a..c0065e6c 100644 --- a/libs/core/src/lib/translation/index.ts +++ b/libs/core/src/lib/translation/index.ts @@ -17,3 +17,5 @@ export { autoTranslateResource } from './auto-translate-resources'; export type { AutoTranslateParams, AutoTranslatedEntry, AutoTranslateResult } from './auto-translate-resources'; export { translateExistingResource } from './translate-existing-resource'; export type { TranslateExistingResourceOptions, TranslateExistingResourceResult } from './translate-existing-resource'; +export { translateLocale } from './translate-locale'; +export type { TranslateLocaleParams, TranslateLocaleProgress, TranslateLocaleResult } from './translate-locale'; diff --git a/libs/core/src/lib/translation/translate-locale.spec.ts b/libs/core/src/lib/translation/translate-locale.spec.ts new file mode 100644 index 00000000..c37f1229 --- /dev/null +++ b/libs/core/src/lib/translation/translate-locale.spec.ts @@ -0,0 +1,422 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import { TranslationError } from './translation-provider'; +import type { TranslationConfig } from '../../config/translation-config'; +import type { TranslateTextResult } from './translation-orchestrator'; +import type { ResourceTreeNode } from '../resource/load-resource-tree'; + +// --------------------------------------------------------------------------- +// Module mocks — must be declared before any imports that reference them +// --------------------------------------------------------------------------- + +vi.mock('../resource/load-resource-tree'); +vi.mock('../resource/extract-subtree'); +vi.mock('../file-io/json-file-operations'); +vi.mock('./translation-provider-factory'); +vi.mock('./translation-orchestrator'); + +import { loadResourceTree } from '../resource/load-resource-tree'; +import { extractResourcesRecursively } from '../resource/extract-subtree'; +import { readResourceEntries, readTrackerMetadata, writeJsonFile } from '../file-io/json-file-operations'; +import { createTranslationProvider } from './translation-provider-factory'; +import { TranslationOrchestrator } from './translation-orchestrator'; +import { translateLocale } from './translate-locale'; + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +const EMPTY_TREE: ResourceTreeNode = { + folderPathSegments: [], + resources: [], + children: [], +}; + +const BASE_CONFIG: TranslationConfig = { + enabled: true, + provider: 'google-translate', + apiKeyEnv: 'GOOGLE_TRANSLATE_API_KEY', + batchSize: 5, + delayMs: 0, // no delay in tests +}; + +function translated(value: string): TranslateTextResult { + return { kind: 'translated', value }; +} + +function skipped(value: string): TranslateTextResult { + return { kind: 'skipped', value }; +} + +function makeResource( + key: string, + source: string, + targetLocaleStatus?: 'new' | 'stale' | 'translated' | 'verified', + targetLocale = 'fr', +) { + return { + key, + source, + translations: {}, + metadata: targetLocaleStatus + ? { + [targetLocale]: { checksum: 'abc', status: targetLocaleStatus }, + en: { checksum: '123' }, + } + : { en: { checksum: '123' } }, + }; +} + +// --------------------------------------------------------------------------- +// Setup +// --------------------------------------------------------------------------- + +const mockTranslateBatchForLocale = vi.fn(); + +beforeEach(() => { + vi.clearAllMocks(); + + process.env.GOOGLE_TRANSLATE_API_KEY = 'test-api-key'; + + vi.mocked(loadResourceTree).mockReturnValue(EMPTY_TREE); + vi.mocked(extractResourcesRecursively).mockReturnValue([]); + + vi.mocked(createTranslationProvider).mockReturnValue({ + translate: vi.fn(), + getCapabilities: vi.fn(), + }); + + vi.mocked(TranslationOrchestrator).mockImplementation( + () => + ({ + translateBatchForLocale: mockTranslateBatchForLocale, + }) as unknown as TranslationOrchestrator, + ); + + // Default mocks return generic entries so any entryKey resolves correctly. + vi.mocked(readResourceEntries).mockReturnValue({ + ok: { source: 'OK' }, + cancel: { source: 'Cancel' }, + a: { source: 'A' }, + b: { source: 'B' }, + c: { source: 'C' }, + key0: { source: 'Text 0' }, + key1: { source: 'Text 1' }, + key2: { source: 'Text 2' }, + key3: { source: 'Text 3' }, + key4: { source: 'Text 4' }, + key5: { source: 'Text 5' }, + } as ReturnType); + vi.mocked(readTrackerMetadata).mockReturnValue({ + ok: { en: { checksum: '123' } }, + cancel: { en: { checksum: '456' } }, + a: { en: { checksum: '111' } }, + b: { en: { checksum: '222' } }, + c: { en: { checksum: '333' } }, + }); + vi.mocked(writeJsonFile).mockImplementation(() => undefined); +}); + +afterEach(() => { + delete process.env.GOOGLE_TRANSLATE_API_KEY; +}); + +// --------------------------------------------------------------------------- +// Tests +// --------------------------------------------------------------------------- + +describe('translateLocale', () => { + const defaultParams = { + translationsFolder: 'src/i18n', + translationConfig: BASE_CONFIG, + targetLocale: 'fr', + baseLocale: 'en', + allLocales: ['en', 'fr'], + cwd: '/project', + }; + + // ------------------------------------------------------------------------- + // Early exit — nothing to translate + // ------------------------------------------------------------------------- + + describe('early exit when nothing needs translating', () => { + it('returns zeroed result when there are no resources at all', async () => { + vi.mocked(extractResourcesRecursively).mockReturnValue([]); + const onProgress = vi.fn(); + + const result = await translateLocale({ ...defaultParams, onProgress }); + + expect(result).toEqual({ + totalResources: 0, + translatedCount: 0, + failedCount: 0, + skippedCount: 0, + failures: [], + skippedKeys: [], + }); + expect(mockTranslateBatchForLocale).not.toHaveBeenCalled(); + expect(onProgress).not.toHaveBeenCalled(); + }); + + it('returns zeroed result when all resources are already translated', async () => { + vi.mocked(extractResourcesRecursively).mockReturnValue([ + makeResource('apps.ok', 'OK', 'translated'), + makeResource('apps.cancel', 'Cancel', 'verified'), + ]); + const onProgress = vi.fn(); + + const result = await translateLocale({ ...defaultParams, onProgress }); + + expect(result.totalResources).toBe(0); + expect(mockTranslateBatchForLocale).not.toHaveBeenCalled(); + expect(onProgress).not.toHaveBeenCalled(); + }); + + it('skips resources with verified status', async () => { + vi.mocked(extractResourcesRecursively).mockReturnValue([makeResource('apps.ok', 'OK', 'verified')]); + const onProgress = vi.fn(); + + const result = await translateLocale({ ...defaultParams, onProgress }); + + expect(result.totalResources).toBe(0); + expect(mockTranslateBatchForLocale).not.toHaveBeenCalled(); + expect(onProgress).not.toHaveBeenCalled(); + }); + }); + + // ------------------------------------------------------------------------- + // Status filtering + // ------------------------------------------------------------------------- + + describe('status filtering', () => { + it('translates resources with new status', async () => { + vi.mocked(extractResourcesRecursively).mockReturnValue([makeResource('ok', 'OK', 'new')]); + mockTranslateBatchForLocale.mockResolvedValueOnce([translated('OK-fr')]); + + const result = await translateLocale(defaultParams); + + expect(result.totalResources).toBe(1); + expect(result.translatedCount).toBe(1); + }); + + it('translates resources with stale status', async () => { + vi.mocked(extractResourcesRecursively).mockReturnValue([makeResource('ok', 'OK', 'stale')]); + mockTranslateBatchForLocale.mockResolvedValueOnce([translated('OK-fr')]); + + const result = await translateLocale(defaultParams); + + expect(result.totalResources).toBe(1); + expect(result.translatedCount).toBe(1); + }); + + it('translates resources with no metadata for the target locale', async () => { + // makeResource without a status means no 'fr' metadata entry. + vi.mocked(extractResourcesRecursively).mockReturnValue([makeResource('ok', 'OK')]); + mockTranslateBatchForLocale.mockResolvedValueOnce([translated('OK-fr')]); + + const result = await translateLocale(defaultParams); + + expect(result.totalResources).toBe(1); + expect(result.translatedCount).toBe(1); + }); + + it('does not translate resources with translated status', async () => { + vi.mocked(extractResourcesRecursively).mockReturnValue([makeResource('ok', 'OK', 'translated')]); + + const result = await translateLocale(defaultParams); + + expect(result.totalResources).toBe(0); + expect(mockTranslateBatchForLocale).not.toHaveBeenCalled(); + }); + }); + + // ------------------------------------------------------------------------- + // Batching + // ------------------------------------------------------------------------- + + describe('batch processing', () => { + it('calls onProgress for each batch', async () => { + const resources = [makeResource('a', 'A', 'new'), makeResource('b', 'B', 'new'), makeResource('c', 'C', 'new')]; + vi.mocked(extractResourcesRecursively).mockReturnValue(resources); + + mockTranslateBatchForLocale + .mockResolvedValueOnce([translated('A-fr'), translated('B-fr')]) + .mockResolvedValueOnce([translated('C-fr')]); + + const progressEvents: number[] = []; + await translateLocale({ + ...defaultParams, + translationConfig: { ...BASE_CONFIG, batchSize: 2, delayMs: 0 }, + onProgress: (p) => progressEvents.push(p.currentBatch), + }); + + expect(progressEvents).toEqual([1, 2]); + }); + + it('respects batchSize when calling the orchestrator', async () => { + const resources = Array.from({ length: 6 }, (_, i) => makeResource(`key${i}`, `Text ${i}`, 'new')); + vi.mocked(extractResourcesRecursively).mockReturnValue(resources); + + mockTranslateBatchForLocale.mockResolvedValue([translated('t1'), translated('t2'), translated('t3')]); + + await translateLocale({ + ...defaultParams, + translationConfig: { ...BASE_CONFIG, batchSize: 3, delayMs: 0 }, + }); + + expect(mockTranslateBatchForLocale).toHaveBeenCalledTimes(2); + }); + + it('reports accurate progress counts in onProgress', async () => { + vi.mocked(extractResourcesRecursively).mockReturnValue([makeResource('ok', 'OK', 'new')]); + mockTranslateBatchForLocale.mockResolvedValueOnce([translated('OK-fr')]); + + let capturedProgress: Parameters>[0] | undefined; + + await translateLocale({ + ...defaultParams, + onProgress: (p) => { + capturedProgress = p; + }, + }); + + expect(capturedProgress).toMatchObject({ + totalResources: 1, + translatedCount: 1, + failedCount: 0, + skippedCount: 0, + currentBatch: 1, + totalBatches: 1, + }); + }); + }); + + // ------------------------------------------------------------------------- + // ICU skipping + // ------------------------------------------------------------------------- + + describe('ICU skipping', () => { + it('adds skipped-ICU resource keys to skippedKeys', async () => { + const icuSource = '{count, plural, one {# item} other {# items}}'; + vi.mocked(extractResourcesRecursively).mockReturnValue([makeResource('ok', icuSource, 'new')]); + mockTranslateBatchForLocale.mockResolvedValueOnce([skipped(icuSource)]); + + const result = await translateLocale(defaultParams); + + expect(result.skippedKeys).toContain('ok'); + expect(result.skippedCount).toBe(1); + expect(result.translatedCount).toBe(0); + }); + + it('does not call writeJsonFile for skipped resources', async () => { + const icuSource = '{count, plural, one {# item} other {# items}}'; + vi.mocked(extractResourcesRecursively).mockReturnValue([makeResource('ok', icuSource, 'new')]); + mockTranslateBatchForLocale.mockResolvedValueOnce([skipped(icuSource)]); + + await translateLocale(defaultParams); + + expect(writeJsonFile).not.toHaveBeenCalled(); + }); + + it('skips writing and increments skippedCount when entryKey is missing from disk entries', async () => { + vi.mocked(extractResourcesRecursively).mockReturnValue([makeResource('ok', 'OK', 'new')]); + mockTranslateBatchForLocale.mockResolvedValueOnce([translated('OK-fr')]); + + // Return an empty object — the 'ok' entry is absent from disk + vi.mocked(readResourceEntries).mockReturnValue({} as ReturnType); + + const result = await translateLocale(defaultParams); + + expect(result.skippedCount).toBe(1); + expect(result.translatedCount).toBe(0); + expect(writeJsonFile).not.toHaveBeenCalled(); + }); + }); + + // ------------------------------------------------------------------------- + // File I/O + // ------------------------------------------------------------------------- + + describe('file I/O', () => { + it('writes entries and meta files once per unique folder', async () => { + // Both resources share the same root folder — grouped write produces 2 files. + vi.mocked(extractResourcesRecursively).mockReturnValue([ + makeResource('ok', 'OK', 'new'), + makeResource('cancel', 'Cancel', 'new'), + ]); + mockTranslateBatchForLocale.mockResolvedValueOnce([translated('OK-fr'), translated('Annuler')]); + + await translateLocale(defaultParams); + + // Two resources in the same folder → one read-modify-write cycle → 2 file writes. + expect(writeJsonFile).toHaveBeenCalledTimes(2); + }); + + it('writes entries and meta files once per unique folder across multiple folders', async () => { + // Resources in two different folders each get their own write cycle. + vi.mocked(extractResourcesRecursively).mockReturnValue([ + makeResource('folderA.ok', 'OK', 'new'), + makeResource('folderB.cancel', 'Cancel', 'new'), + ]); + mockTranslateBatchForLocale.mockResolvedValueOnce([translated('OK-fr'), translated('Annuler')]); + + await translateLocale(defaultParams); + + // Two distinct folders → 2 read-modify-write cycles → 4 file writes. + expect(writeJsonFile).toHaveBeenCalledTimes(4); + }); + }); + + // ------------------------------------------------------------------------- + // Error handling + // ------------------------------------------------------------------------- + + describe('error handling', () => { + it('throws TranslationError with MISSING_API_KEY when the env var is absent', async () => { + delete process.env.GOOGLE_TRANSLATE_API_KEY; + vi.mocked(extractResourcesRecursively).mockReturnValue([makeResource('ok', 'OK', 'new')]); + + await expect(translateLocale(defaultParams)).rejects.toMatchObject({ + code: 'MISSING_API_KEY', + retryable: false, + }); + }); + + it('records all resources in a failed batch as failures and continues', async () => { + const resources = [makeResource('a', 'A', 'new'), makeResource('b', 'B', 'new'), makeResource('c', 'C', 'new')]; + vi.mocked(extractResourcesRecursively).mockReturnValue(resources); + + const providerError = new TranslationError('quota exceeded', 'RATE_LIMIT', true); + + mockTranslateBatchForLocale + .mockRejectedValueOnce(providerError) // batch 1 fails + .mockResolvedValueOnce([translated('C-fr')]); // batch 2 succeeds + + const result = await translateLocale({ + ...defaultParams, + translationConfig: { ...BASE_CONFIG, batchSize: 2, delayMs: 0 }, + }); + + expect(result.failedCount).toBe(2); + expect(result.translatedCount).toBe(1); + expect(result.failures).toHaveLength(2); + expect(result.failures[0].key).toBe('a'); + expect(result.failures[1].key).toBe('b'); + }); + + it('continues processing subsequent batches after a batch failure', async () => { + const resources = [makeResource('a', 'A', 'new'), makeResource('b', 'B', 'new')]; + vi.mocked(extractResourcesRecursively).mockReturnValue(resources); + + const providerError = new TranslationError('fail', 'SERVER_ERROR', true); + mockTranslateBatchForLocale.mockRejectedValueOnce(providerError).mockResolvedValueOnce([translated('B-fr')]); + + const result = await translateLocale({ + ...defaultParams, + translationConfig: { ...BASE_CONFIG, batchSize: 1, delayMs: 0 }, + }); + + expect(result.failedCount).toBe(1); + expect(result.translatedCount).toBe(1); + }); + }); +}); diff --git a/libs/core/src/lib/translation/translate-locale.ts b/libs/core/src/lib/translation/translate-locale.ts new file mode 100644 index 00000000..991a0804 --- /dev/null +++ b/libs/core/src/lib/translation/translate-locale.ts @@ -0,0 +1,305 @@ +/** + * Bulk locale translation. + * + * Translates all `new` and `stale` resources in a translations folder for a + * single target locale. Resources are processed in batches so that the number + * of API calls is bounded regardless of how many resources exist. + * + * Complex ICU resources (plural, select, etc.) are automatically skipped by + * the underlying {@link TranslationOrchestrator} and reported in `skippedKeys`. + * + * @module translate-locale + */ + +import * as path from 'node:path'; +import { loadResourceTree } from '../resource/load-resource-tree'; +import { extractResourcesRecursively } from '../resource/extract-subtree'; +import { readResourceEntries, readTrackerMetadata, writeJsonFile } from '../file-io/json-file-operations'; +import { calculateChecksum } from '../../resource/checksum'; +import { createTranslationProvider } from './translation-provider-factory'; +import { TranslationOrchestrator } from './translation-orchestrator'; +import { TranslationError } from './translation-provider'; +import { RESOURCE_ENTRIES_FILENAME, TRACKER_META_FILENAME } from '../../constants'; +import type { TranslationConfig } from '../../config/translation-config'; +import type { ResourceTreeEntry } from '../resource/load-resource-tree'; + +// --------------------------------------------------------------------------- +// Public interfaces +// --------------------------------------------------------------------------- + +export interface TranslateLocaleParams { + readonly translationsFolder: string; + readonly translationConfig: TranslationConfig; + readonly targetLocale: string; + readonly baseLocale: string; + readonly allLocales: string[]; + readonly cwd?: string; + readonly onProgress?: (progress: TranslateLocaleProgress) => void; +} + +export interface TranslateLocaleProgress { + /** + * Number of resources eligible for translation (status `new`, `stale`, or missing metadata + * for the target locale). Does NOT represent the total collection size. + * Returns 0 when no resources needed translation. + */ + readonly totalResources: number; + readonly translatedCount: number; + readonly failedCount: number; + readonly skippedCount: number; + readonly currentBatch: number; + readonly totalBatches: number; +} + +export interface TranslateLocaleResult { + /** + * Number of resources eligible for translation (status `new`, `stale`, or missing metadata + * for the target locale). Does NOT represent the total collection size. + * Returns 0 when no resources needed translation. + */ + readonly totalResources: number; + readonly translatedCount: number; + readonly failedCount: number; + readonly skippedCount: number; + readonly failures: ReadonlyArray<{ key: string; error: string }>; + readonly skippedKeys: string[]; +} + +// --------------------------------------------------------------------------- +// Internal helpers +// --------------------------------------------------------------------------- + +function sleep(ms: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +/** + * Returns true when a resource needs translation for `targetLocale`. + * A resource needs translation when its status is `new`, `stale`, + * or when there is no metadata at all for the locale. + */ +function needsTranslation(resource: ResourceTreeEntry, targetLocale: string): boolean { + const meta = resource.metadata[targetLocale]; + if (!meta) return true; + return meta.status === 'new' || meta.status === 'stale'; +} + +/** + * Converts a dot-delimited composite key (e.g. `apps.common.buttons.ok`) + * into the filesystem folder path (e.g. `apps/common/buttons`) and the + * entry key (`ok`). + */ +function resolveResourcePath( + compositeKey: string, + absoluteTranslationsFolder: string, +): { folderPath: string; entryKey: string } { + const segments = compositeKey.split('.'); + const entryKey = segments[segments.length - 1]; + const folderSegments = segments.slice(0, -1); + const folderPath = + folderSegments.length > 0 ? path.join(absoluteTranslationsFolder, ...folderSegments) : absoluteTranslationsFolder; + + return { folderPath, entryKey }; +} + +// --------------------------------------------------------------------------- +// Internal types +// --------------------------------------------------------------------------- + +interface FolderWriteEntry { + readonly entryKey: string; + readonly result: { kind: string; value: string }; + readonly source: string; + readonly resourceKey: string; +} + +// --------------------------------------------------------------------------- +// Internal helpers (continued) +// --------------------------------------------------------------------------- + +/** + * Reads the entries and metadata files for a folder once, applies all + * translated resources for that folder, and writes both files back once. + * Resources whose entry key is missing from disk are silently skipped. + * + * @returns How many entries were actually written (missing entries are 0). + */ +function writeTranslatedResources( + folderPath: string, + entries: readonly FolderWriteEntry[], + targetLocale: string, + baseLocale: string, +): { + writtenKeys: string[]; + skippedKeys: string[]; +} { + const entriesFilePath = path.join(folderPath, RESOURCE_ENTRIES_FILENAME); + const metaFilePath = path.join(folderPath, TRACKER_META_FILENAME); + + const resourceEntries = readResourceEntries(entriesFilePath, {}); + const trackerMeta = readTrackerMetadata(metaFilePath, {}); + + const writtenKeys: string[] = []; + const skippedKeys: string[] = []; + + for (const entry of entries) { + if (!resourceEntries[entry.entryKey]) { + skippedKeys.push(entry.resourceKey); + continue; + } + + (resourceEntries[entry.entryKey] as Record)[targetLocale] = entry.result.value; + + const baseChecksum = trackerMeta[entry.entryKey]?.[baseLocale]?.checksum ?? calculateChecksum(entry.source); + trackerMeta[entry.entryKey] = { + ...trackerMeta[entry.entryKey], + [targetLocale]: { + checksum: calculateChecksum(entry.result.value), + baseChecksum, + status: 'translated', + }, + }; + + writtenKeys.push(entry.resourceKey); + } + + if (writtenKeys.length > 0) { + writeJsonFile({ filePath: entriesFilePath, data: resourceEntries }); + writeJsonFile({ filePath: metaFilePath, data: trackerMeta }); + } + + return { writtenKeys, skippedKeys }; +} + +// --------------------------------------------------------------------------- +// Main export +// --------------------------------------------------------------------------- + +/** + * Translates all `new` and `stale` resources in `translationsFolder` for the + * given `targetLocale`, writing the results back to disk. + * + * Resources are processed in batches of `translationConfig.batchSize` (default 5). + * A configurable delay (`translationConfig.delayMs`, default 1000 ms) is inserted + * between batches to avoid hitting provider rate limits. + * + * Complex ICU messages (plural, select, etc.) are silently skipped and their keys + * are included in `TranslateLocaleResult.skippedKeys`. Provider-level errors mark + * all resources in the failing batch as failed but do not abort the run. + * + * @param params - Translation parameters. + * @returns A summary of how many resources were translated, skipped, or failed. + * @throws {TranslationError} with code `MISSING_API_KEY` when the env var is absent. + */ +export async function translateLocale(params: TranslateLocaleParams): Promise { + const { translationConfig, targetLocale, baseLocale, cwd = process.cwd(), onProgress } = params; + + const absoluteFolder = path.resolve(cwd, params.translationsFolder); + + // Load the entire resource tree. + const tree = loadResourceTree({ translationsFolder: absoluteFolder, depth: 999, cwd }); + const allResources = extractResourcesRecursively(tree); + + // Filter to only those that need translating for the target locale. + const resourcesToTranslate = allResources.filter((resource) => needsTranslation(resource, targetLocale)); + + if (resourcesToTranslate.length === 0) { + return { + totalResources: 0, + translatedCount: 0, + failedCount: 0, + skippedCount: 0, + failures: [], + skippedKeys: [], + }; + } + + // Resolve the API key once — fail fast before doing any I/O. + const apiKey = process.env[translationConfig.apiKeyEnv]; + if (!apiKey) { + throw new TranslationError( + `Translation API key not found. Set the ${translationConfig.apiKeyEnv} environment variable.`, + 'MISSING_API_KEY', + false, + ); + } + + const provider = createTranslationProvider(translationConfig.provider, apiKey); + const orchestrator = new TranslationOrchestrator(provider); + + const batchSize = translationConfig.batchSize ?? 5; + const delayMs = translationConfig.delayMs ?? 1000; + + const totalResources = resourcesToTranslate.length; + const totalBatches = Math.ceil(totalResources / batchSize); + + let translatedCount = 0; + let failedCount = 0; + let skippedCount = 0; + const failures: Array<{ key: string; error: string }> = []; + const skippedKeys: string[] = []; + + for (let batchIndex = 0; batchIndex < totalBatches; batchIndex++) { + const batchStart = batchIndex * batchSize; + const batch = resourcesToTranslate.slice(batchStart, batchStart + batchSize); + const sourceTexts = batch.map((resource) => resource.source); + + try { + const batchResults = await orchestrator.translateBatchForLocale(sourceTexts, baseLocale, targetLocale); + + // Group translated results by folder so each folder's files are read and + // written only once, even when multiple resources share the same folder. + const byFolder = new Map(); + + for (let i = 0; i < batch.length; i++) { + const resource = batch[i]; + const result = batchResults[i]; + + if (result.kind === 'skipped') { + skippedKeys.push(resource.key); + skippedCount++; + continue; + } + + const { folderPath, entryKey } = resolveResourcePath(resource.key, absoluteFolder); + const folderEntries = byFolder.get(folderPath) ?? []; + folderEntries.push({ entryKey, result, source: resource.source, resourceKey: resource.key }); + byFolder.set(folderPath, folderEntries); + } + + for (const [folderPath, folderEntries] of byFolder) { + const { writtenKeys, skippedKeys: folderSkippedKeys } = writeTranslatedResources( + folderPath, + folderEntries, + targetLocale, + baseLocale, + ); + translatedCount += writtenKeys.length; + skippedCount += folderSkippedKeys.length; + skippedKeys.push(...folderSkippedKeys); + } + } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + for (const resource of batch) { + failures.push({ key: resource.key, error: errorMessage }); + failedCount++; + } + } + + onProgress?.({ + totalResources, + translatedCount, + failedCount, + skippedCount, + currentBatch: batchIndex + 1, + totalBatches, + }); + + // Pause between batches (skip after the last one). + if (batchIndex < totalBatches - 1) { + await sleep(delayMs); + } + } + + return { totalResources, translatedCount, failedCount, skippedCount, failures, skippedKeys }; +} diff --git a/libs/core/src/lib/translation/translation-orchestrator.spec.ts b/libs/core/src/lib/translation/translation-orchestrator.spec.ts index 5929e79e..e01a8404 100644 --- a/libs/core/src/lib/translation/translation-orchestrator.spec.ts +++ b/libs/core/src/lib/translation/translation-orchestrator.spec.ts @@ -306,4 +306,113 @@ describe('TranslationOrchestrator', () => { expect(provider.translate).toHaveBeenCalledOnce(); }); }); + + // ------------------------------------------------------------------------- + // translateBatchForLocale + // ------------------------------------------------------------------------- + + describe('translateBatchForLocale', () => { + it('returns an empty array for an empty input without calling the provider', async () => { + const results = await orchestrator.translateBatchForLocale([], 'en', 'de'); + + expect(results).toEqual([]); + expect(provider.translate).not.toHaveBeenCalled(); + }); + + it('returns results in the same order as the input texts', async () => { + provider.translate.mockResolvedValueOnce([makeResult('Hallo'), makeResult('Tschüss')]); + + const results = await orchestrator.translateBatchForLocale(['Hello', 'Goodbye'], 'en', 'de'); + + expect(results[0]).toEqual({ kind: 'translated', value: 'Hallo' }); + expect(results[1]).toEqual({ kind: 'translated', value: 'Tschüss' }); + }); + + it('skips complex ICU texts immediately without including them in the provider call', async () => { + const icuText = '{count, plural, one {# item} other {# items}}'; + + const results = await orchestrator.translateBatchForLocale([icuText], 'en', 'de'); + + expect(results).toEqual([{ kind: 'skipped', value: icuText }]); + expect(provider.translate).not.toHaveBeenCalled(); + }); + + it('sends all plain texts to the provider in a single call', async () => { + provider.translate.mockResolvedValueOnce([makeResult('Hallo'), makeResult('Welt')]); + + await orchestrator.translateBatchForLocale(['Hello', 'World'], 'en', 'de'); + + expect(provider.translate).toHaveBeenCalledOnce(); + expect(provider.translate).toHaveBeenCalledWith([ + { text: 'Hello', sourceLocale: 'en', targetLocale: 'de' }, + { text: 'World', sourceLocale: 'en', targetLocale: 'de' }, + ]); + }); + + it('protects and restores placeholders for simple-placeholder texts', async () => { + provider.translate.mockImplementation(async (requests: TranslateRequest[]) => { + // Simulate translation of surrounding text while leaving span markers intact. + return requests.map((req) => makeResult(req.text.replace('Hello', 'Hallo'))); + }); + + const results = await orchestrator.translateBatchForLocale(['Hello {name}'], 'en', 'de'); + + expect(results[0].kind).toBe('translated-with-placeholders'); + expect(results[0].value).toBe('Hallo {name}'); + }); + + it('falls back to skipped when the provider drops a placeholder marker', async () => { + provider.translate.mockResolvedValueOnce([makeResult('Hallo')]); + + const results = await orchestrator.translateBatchForLocale(['Hello {name}'], 'en', 'de'); + + expect(results[0]).toEqual({ kind: 'skipped', value: 'Hello {name}' }); + }); + + it('calls the provider exactly once for a mixed batch of plain, simple-placeholder, and complex ICU texts', async () => { + const complexIcu = '{count, plural, one {# item} other {# items}}'; + + // Provider receives: plain text + protected simple-placeholder text (complex ICU is excluded). + provider.translate.mockImplementation(async (requests: TranslateRequest[]) => { + return requests.map((req) => makeResult(req.text.replace('Hello', 'Hallo'))); + }); + + const results = await orchestrator.translateBatchForLocale(['Hello', 'Hello {name}', complexIcu], 'en', 'de'); + + expect(provider.translate).toHaveBeenCalledOnce(); + expect(results[0]).toEqual({ kind: 'translated', value: 'Hallo' }); + expect(results[1].kind).toBe('translated-with-placeholders'); + expect(results[1].value).toBe('Hallo {name}'); + expect(results[2]).toEqual({ kind: 'skipped', value: complexIcu }); + }); + + it('returns kind: skipped for all items and never calls the provider when every item is complex ICU', async () => { + const icuPlural = '{count, plural, one {# item} other {# items}}'; + const icuSelect = '{gender, select, male {he} female {she} other {they}}'; + const icuMixed = 'Hello {name}, {count, plural, one {# item} other {# items}}'; + + const results = await orchestrator.translateBatchForLocale([icuPlural, icuSelect, icuMixed], 'en', 'de'); + + expect(provider.translate).not.toHaveBeenCalled(); + expect(results).toHaveLength(3); + expect(results[0]).toEqual({ kind: 'skipped', value: icuPlural }); + expect(results[1]).toEqual({ kind: 'skipped', value: icuSelect }); + expect(results[2]).toEqual({ kind: 'skipped', value: icuMixed }); + }); + + it('preserves order when complex ICU items are interspersed with translatable items', async () => { + const complexIcu = '{gender, select, male {he} female {she} other {they}}'; + + provider.translate.mockResolvedValueOnce([makeResult('Hallo'), makeResult('Tschüss')]); + + const results = await orchestrator.translateBatchForLocale(['Hello', complexIcu, 'Goodbye'], 'en', 'de'); + + expect(results[0]).toEqual({ kind: 'translated', value: 'Hallo' }); + expect(results[1]).toEqual({ kind: 'skipped', value: complexIcu }); + expect(results[2]).toEqual({ kind: 'translated', value: 'Tschüss' }); + // Only two texts were sent to the provider (Hello and Goodbye, not the ICU). + expect(provider.translate).toHaveBeenCalledOnce(); + expect(provider.translate.mock.calls[0][0]).toHaveLength(2); + }); + }); }); diff --git a/libs/core/src/lib/translation/translation-orchestrator.ts b/libs/core/src/lib/translation/translation-orchestrator.ts index b7442518..b8593c2d 100644 --- a/libs/core/src/lib/translation/translation-orchestrator.ts +++ b/libs/core/src/lib/translation/translation-orchestrator.ts @@ -123,6 +123,101 @@ export class TranslationOrchestrator { return results; } + /** + * Translates multiple texts for a single target locale in one provider call. + * + * This is the key optimization for bulk locale translation: rather than making + * one provider call per resource, all translatable texts are collected and sent + * in a single call (the provider handles its own internal chunking at 128 items). + * + * Complex ICU texts are classified and skipped immediately without any API call. + * Simple-placeholder texts have their placeholders protected before sending and + * restored from the translated result; a marker mismatch falls back to `kind: 'skipped'`. + * + * Results are returned in the same order as the input `texts` array. + * + * @param texts - Array of source strings to translate. + * @param sourceLocale - BCP 47 locale code of the source texts. + * @param targetLocale - BCP 47 locale code to translate into. + * @returns Results in the same order as the input. + * @throws {TranslationError} for any provider-level failure. + */ + async translateBatchForLocale( + texts: string[], + sourceLocale: string, + targetLocale: string, + ): Promise { + if (texts.length === 0) { + return []; + } + + type TextKind = 'plain' | 'simple-placeholders' | 'complex-icu'; + const classifications: TextKind[] = texts.map((text) => classifyICUContent(text)); + + // Collect translatable texts (plain + protected simple-placeholder) in one flat array, + // preserving an index so we can map results back to the original input positions. + const providerInputs: Array<{ text: string; originalIndex: number }> = []; + + // For simple-placeholder items we need the protect result to restore later. + const placeholderMaps = new Map['placeholders']>(); + + for (let i = 0; i < texts.length; i++) { + const kind = classifications[i]; + if (kind === 'complex-icu') continue; + + if (kind === 'plain') { + providerInputs.push({ text: texts[i], originalIndex: i }); + } else { + // simple-placeholders + const { protectedText, placeholders } = protectPlaceholders(texts[i]); + placeholderMaps.set(i, placeholders); + providerInputs.push({ text: protectedText, originalIndex: i }); + } + } + + let providerResults: Array<{ translatedText: string }> = []; + if (providerInputs.length > 0) { + providerResults = await this.#provider.translate( + providerInputs.map(({ text }) => ({ text, sourceLocale, targetLocale })), + ); + } + + const results: TranslateTextResult[] = new Array(texts.length); + + // Fill complex-ICU skips first. + for (let i = 0; i < texts.length; i++) { + if (classifications[i] === 'complex-icu') { + results[i] = { kind: 'skipped', value: texts[i] }; + } + } + + // Fill translated results. + for (let providerIdx = 0; providerIdx < providerInputs.length; providerIdx++) { + const { originalIndex } = providerInputs[providerIdx]; + const translatedText = providerResults[providerIdx].translatedText; + const kind = classifications[originalIndex]; + + if (kind === 'plain') { + results[originalIndex] = { kind: 'translated', value: translatedText }; + } else { + // simple-placeholders — restore markers + const placeholders = placeholderMaps.get(originalIndex); + if (!placeholders) { + results[originalIndex] = { kind: 'skipped', value: texts[originalIndex] }; + continue; + } + const restoreResult = restorePlaceholders(translatedText, placeholders); + if (!restoreResult.success) { + results[originalIndex] = { kind: 'skipped', value: texts[originalIndex] }; + } else { + results[originalIndex] = { kind: 'translated-with-placeholders', value: restoreResult.value }; + } + } + } + + return results; + } + /** * Protects simple placeholders with markers, translates the protected text, * then restores the original placeholder syntax. diff --git a/libs/data-transfer/src/index.ts b/libs/data-transfer/src/index.ts index 0593f777..34ca98f2 100644 --- a/libs/data-transfer/src/index.ts +++ b/libs/data-transfer/src/index.ts @@ -22,3 +22,7 @@ export * from './lib/tree-status-response.dto'; export * from './lib/translation-config.dto'; export * from './lib/translate-resource.dto'; export * from './lib/translate-resource-response.dto'; +export * from './lib/translate-locale.dto'; +export * from './lib/add-locale.dto'; +export * from './lib/add-locale-response.dto'; +export * from './lib/remove-locale-response.dto'; diff --git a/libs/data-transfer/src/lib/add-locale-response.dto.ts b/libs/data-transfer/src/lib/add-locale-response.dto.ts new file mode 100644 index 00000000..13d0f19d --- /dev/null +++ b/libs/data-transfer/src/lib/add-locale-response.dto.ts @@ -0,0 +1,5 @@ +export interface AddLocaleResponseDto { + message: string; + entriesBackfilled: number; + filesUpdated: number; +} diff --git a/libs/data-transfer/src/lib/add-locale.dto.ts b/libs/data-transfer/src/lib/add-locale.dto.ts new file mode 100644 index 00000000..41b58d9d --- /dev/null +++ b/libs/data-transfer/src/lib/add-locale.dto.ts @@ -0,0 +1,3 @@ +export interface AddLocaleDto { + locale: string; +} diff --git a/libs/data-transfer/src/lib/remove-locale-response.dto.ts b/libs/data-transfer/src/lib/remove-locale-response.dto.ts new file mode 100644 index 00000000..0da1b42a --- /dev/null +++ b/libs/data-transfer/src/lib/remove-locale-response.dto.ts @@ -0,0 +1,5 @@ +export interface RemoveLocaleResponseDto { + message: string; + entriesPurged: number; + filesUpdated: number; +} diff --git a/libs/data-transfer/src/lib/translate-locale.dto.ts b/libs/data-transfer/src/lib/translate-locale.dto.ts new file mode 100644 index 00000000..3bd0dcfc --- /dev/null +++ b/libs/data-transfer/src/lib/translate-locale.dto.ts @@ -0,0 +1,18 @@ +export interface TranslateLocaleRequestDto { + readonly locale: string; +} + +export interface TranslateLocaleJobDto { + readonly jobId: string; + readonly collectionName: string; + readonly targetLocale: string; + readonly status: 'pending' | 'running' | 'completed' | 'failed'; + readonly totalResources: number; + readonly translatedCount: number; + readonly failedCount: number; + readonly skippedCount: number; + readonly failures?: ReadonlyArray<{ key: string; error: string }>; + readonly skippedKeys?: readonly string[]; + readonly startedAt?: string; + readonly completedAt?: string; +} diff --git a/libs/data-transfer/src/lib/translation-config.dto.ts b/libs/data-transfer/src/lib/translation-config.dto.ts index d8b83fb1..43306c1a 100644 --- a/libs/data-transfer/src/lib/translation-config.dto.ts +++ b/libs/data-transfer/src/lib/translation-config.dto.ts @@ -2,4 +2,8 @@ export interface TranslationConfigDto { readonly enabled: boolean; readonly provider: string; readonly apiKeyEnv: string; + /** Number of resources to send per API batch when translating a full locale. Defaults to 5. */ + readonly batchSize?: number; + /** Milliseconds to wait between batches to avoid rate-limit errors. Defaults to 1000. */ + readonly delayMs?: number; } diff --git a/package.json b/package.json index cb259dab..df7d05f2 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,9 @@ "format": "pnpm exec biome format --write apps libs scripts types", "format:check": "pnpm exec biome format apps libs scripts types", "format:write": "pnpm exec biome format --write apps libs scripts types", - "lingo-tracker": "node dist/apps/cli/main.cjs" + "lingo-tracker": "node dist/apps/cli/main.cjs", + "docs:dev": "cd docs-site && pnpm start", + "docs:build": "cd docs-site && pnpm build" }, "keywords": [ "translation",